在混合类型数组上使用XmlTextAttribute会删除空白字符串

时间:2013-11-13 17:08:38

标签: c# xml linq-to-xml xmlserializer

我正在编写一组必须按照我无法更改的严格规范进行Xml序列化的对象。本规范中的一个元素可以包含字符串和元素的混合。

这个Xml输出的一个简单例子是:

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

请注意第一个标记的关闭和第二个标记的开头之间的空格字符。以下是表示此结构的对象:

[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文件序列化回Root对象时,我称之为:

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数组中有四个对象。其中一个是空间。序列化很好,但是反序列化时,Elements中只有3个对象。空白字符串被删除。

关于我做错的任何想法?我尝试过使用xml:space =“preserve”,以及一系列XmlReader,XmlTextReader等变体。请注意,当我使用StringBuilder读取XmlTextReader时,xml包含我期望的空格。只有在调用Deserialize(stream)时才会丢失空格。

这是一个完整工作示例的链接。它是LinqPad友好的,只需复制/粘贴:http://pastebin.com/8MkUQviB该示例打开两个文件,一个是完美的序列化xml文件,第二个是第一个文件的反序列​​化然后重新编译的版本。请注意,您必须引用System.Xml.Serialization。

感谢您阅读这部小说。我希望有人有一些想法。谢谢!

1 个答案:

答案 0 :(得分:0)

它看起来像一个bug。解决方法似乎是用&amp;#32;替换XML文本节点中的所有空格和crlf。 &安培;#10; &安培;#13;实体。语义相等的实体(&amp;#x20;&amp;#x0a;&amp; #x0d;)不起作用。

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

正在为我工​​作。