2

ここに私のプログラムがあります -

module Program
open System
open System.IO
open System.Text  
open System.Xml
open System.Xml.Serialization
open System.Runtime.Serialization
open System.Reflection
open Microsoft.FSharp.Reflection

let getUnionTypes<'a> () =
    let nestedTypes = typedefof<'a>.GetNestedTypes(BindingFlags.Public ||| BindingFlags.NonPublic) 
    Array.filter FSharpType.IsUnion nestedTypes

type Alpha =
    { X : int * int
      Y : Alpha option }

type [<KnownType "GetTypes">] Beta =
    | A of int * Alpha
    | B of Beta option
    | C of Map<int, Beta>
    static member GetTypes () = getUnionTypes<Beta> ()

let [<EntryPoint>] main _ =
    let alpha = { X = (0, 0); Y = Some { X = (1, 1); Y = None }}
    let betaA = A (0, alpha)
    let betaB = B (Some betaA)
    let betaC = C (Map.singleton 0 betaB)
    let sb = new StringBuilder()
    let xmlSerializer = DataContractSerializer(typeof<Beta>); 
    xmlSerializer.WriteObject(new XmlTextWriter(new StringWriter(sb)), betaC)
    let sr = sb.ToString()
    printfn "%A" sr
    0

出力は次のとおりです-

"<Program.Beta xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="Progr
am.Beta.C" xmlns="http://schemas.datacontract.org/2004/07/"><item xmlns:d2p1="ht
tp://schemas.datacontract.org/2004/07/Microsoft.FSharp.Collections"><d2p1:serial
izedData xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Collections.
Generic"><d3p1:KeyValuePairOfintProgram.BetalLTIrbuF><d3p1:key>0</d3p1:key><d3p1
:value i:type="Program.Beta.B"><item xmlns:d6p1="http://schemas.datacontract.org
/2004/07/Microsoft.FSharp.Core"><d6p1:value i:type="Program.Beta.A"><item1>0</it
em1><item2><X_x0040_ xmlns:d9p1="http://schemas.datacontract.org/2004/07/System"
><d9p1:m_Item1>0</d9p1:m_Item1><d9p1:m_Item2>0</d9p1:m_Item2></X_x0040_><Y_x0040
_><d6p1:value><X_x0040_ xmlns:d11p1="http://schemas.datacontract.org/2004/07/Sys
tem"><d11p1:m_Item1>1</d11p1:m_Item1><d11p1:m_Item2>1</d11p1:m_Item2></X_x0040_>
<Y_x0040_ i:nil="true" /></d6p1:value></Y_x0040_></item2></d6p1:value></item></d
3p1:value></d3p1:KeyValuePairOfintProgram.BetalLTIrbuF></d2p1:serializedData></i
tem></Program.Beta>"

この XML 出力を改善するには、どのような簡単なことをすればよいでしょうか? さまざまな属性を試しましたが、どれも役に立たないようでした。データ構造を不変に保つ必要があることに注意してください。また、可能であれば、独自のシリアル化ライブラリを作成したり、別の自作ライブラリに依存関係を追加したりしたくないことに注意してください。理想的には、単純なソリューションである必要があります。

4

2 に答える 2

1

この XML 出力を改善するには、どのような簡単なことをすればよいでしょうか?

.NET はシリアライゼーションに対してひどいサポートをしており、脆弱で非常に冗長なメッセージを生成するのに長い時間がかかります。使用しないことを強くお勧めします。

F# での XML シリアル化に関する (無料ではない) 記事を書きました。リフレクションを使用して、F# 型の任意の値を分解し、それらを XML に変換してから再び元に戻しました。組み込みのシリアライザーよりもパフォーマンスがはるかに優れており、変換は名目上のものではなく構造的なものであるため、(F# インタラクティブを使用するなどして) 同一の型定義に読み戻すことができますが、OCaml の組み込みのシリアライゼーションのような競合他社よりもはるかに低速です。その記事のコードを使用して、次のことを行います。

> serialize betaC;;
val it : string =
  "<unionCase><name>C</name><map><keyValue><int>0</int><unionCase><name>B</name><unionCase><name>Some</name><unionCase><name>A</name><int>0</int><record><field><name>X</name><value><tuple><int>0</int><int>0</int></tuple></value></field><field><name>Y</name><value><unionCase><name>Some</name><record><field><name>X</name><value><tuple><int>1</int><int>1</int></tuple></value></field><field><name>Y</name><value><unionCase><name>None</name></unionCase></value></field></record></unionCase></value></field></record></unionCase></unionCase></unionCase></keyValue></map></unionCase>"
于 2013-08-05T22:42:41.327 に答える
0

シリアル化後に結果の文字列をきれいに印刷できます。

XDocument.Parse(sr).ToString()

これは、System.Xml.Linqアセンブリと名前空間にあります。

于 2013-08-03T07:07:38.733 に答える