0

変更できない厳密な仕様に従って、Xml との間でシリアル化する必要がある一連のオブジェクトを作成しています。この仕様の 1 つの要素には、文字列と要素をインラインで混在させることができます。

この Xml 出力の簡単な例は次のようになります。

    <root>Leading text <tag>tag1</tag>    <tag>tag2</tag></root>

最初のタグの終了と 2 番目のタグの開始の間の空白文字に注意してください。この構造を表すオブジェクトは次のとおりです。

[XmlRoot("root")]
public class Root
{
   [XmlText(typeof(string))]
   [XmlElement("tag", typeof(Tag))]
   public List<object> Elements { get; set; }

   //this is simply for the sake of example.
   //gives us four objects in the elements array
   public static Root Create()
   {
      Root root = new Root();

      root.Elements.Add("Leading text ");
      root.Elements.Add(new Tag() { Text = "tag1" });
      root.Elements.Add("    ");
      root.Elements.Add(new Tag() { Text = "tag2" });

      return root;
   }

   public Root()
   {
      Elements = new List<object>();
   }
}

public class Tag
{
   [XmlText]
   public string Text {get;set;}
}

Root.Create() を呼び出し、このメソッドを使用してファイルに保存すると、完璧に見えます。

public XDocument SerializeToXml(Root obj)
{
    XmlSerializer serializer = new XmlSerializer(typeof(Root));
    XDocument doc = new XDocument();
    using (var writer = doc.CreateWriter())
    {
        serializer.Serialize(writer, obj);
    }

    return doc;
}

シリアライゼーションは、この投稿の冒頭にある xml 構造とまったく同じように見えます。

xml ファイルをシリアル化してルート オブジェクトに戻したい場合は、次のように呼び出します。

public static Root FromFile(string file)
{
    XmlSerializer serializer = new XmlSerializer(typeof(Root));  

    XmlReaderSettings settings = new XmlReaderSettings();
    XmlReader reader = XmlTextReader.Create(file, settings);

    //whitespace gone here
    Root root = serializer.Deserialize(reader) as Root;
    return root;
}

問題はここにあります。空白文字列は削除されます。Root.Create() を呼び出すと、Elements 配列に 4 つのオブジェクトがあります。その一つがスペースです。これは問題なくシリアル化されますが、逆シリアル化すると、Elements には 3 つのオブジェクトしかありません。空白文字列は削除されます。

私が間違っていることについてのアイデアはありますか?私は xml:space="preserve" と、XmlReader、XmlTextReader などのバリエーションのホストを使用してみました。StringBuilder を使用して XmlTextReader を読み取ると、期待どおりに xml にスペースが含まれることに注意してください。Deserialize(stream) を呼び出すときにのみ、スペースが失われます。

これは、実際の作業例全体へのリンクです。これは LinqPad フレンドリーで、コピー/貼り付けするだけです: http://pastebin.com/8MkUQviBこの例では 2 つのファイルを開きます。System.Xml.Serialization を参照する必要があることに注意してください。

この小説を読んでくれてありがとう。誰かがアイデアを持っていることを願っています。ありがとうございました!

4

1 に答える 1

0

バグのようです。回避策は、XML テキスト ノード内のすべての空白と crlf を に置き換えることです。 エンティティ。セマンティック イコール エンティティ ( ) は機能しません。

<root>Leading text <tag>tag1</tag>&#32;&#32;&#32;<tag>tag2</tag></root>

私のために働いています。

于 2014-10-02T12:21:30.780 に答える