Xml序列化具有自定义标记名称的不同类的数组

时间:2012-02-17 12:15:19

标签: c# arrays xml-serialization

假设我有以下类结构:

[XmlInclude(typeof(CustomNode))]
[XmlInclude(typeof(CustomNode2))]
[XmlRoot("node")]
class Node
{
    [XmlElement("node")]
    public Node[] Children { get; set; }
}
[XmlRoot("custom-node")]
class CustomNode : Node { }
[XmlRoot("custom-node-2")]
class CustomNode2 : Node { }

我创建了以下结构:

var root = new Node { Children = new Node[2] };
root.Children[0] = new CustomNode();
root.Children[1] = new CustomNode2();

当我Xml序列化这个结构时,我得到以下输出:

<node>
    <node xsi:Type="CustomNode"/>
    <node xsi:Type="CustomNode2"/>
</node>

但我希望看到(并且能够正确加载)这样的东西:

<node>
    <custom-node/>
    <custom-node-2/>
</node>

XmlSerializer可以吗?整个问题是因为我打算手动创建source xml,并且我试图让它变得更加人性化和友好。

2 个答案:

答案 0 :(得分:6)

我为您的问题找到了一个几乎所需的解决方案:

  [XmlRoot(ElementName = "node")]
  public class Node
  {
    [XmlArrayItem(typeof(CustomNode), ElementName = "custom-node")]
    [XmlArrayItem(typeof(CustomNode2), ElementName = "custom-node-2")] 
    public List<Node> Children { get; set; }     
  }
  [XmlRoot(ElementName = "custom-node")]
  public class CustomNode : Node { }
  [XmlRoot(ElementName = "custom-node-2")]
  public class CustomNode2 : Node { }

结果:

<node xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Children>
    <custom-node />
    <custom-node-2 />
  </Children>
</node>

希望有所帮助。

答案 1 :(得分:0)

如果您只使用各种xml属性来指定xml,我认为您无法说服XmlSerializer输出此xml。

如果类型本身不在根目录(而不是在另一个类中组合),则忽略您尝试使用的[XmlRoot]属性。

但是,您可以实施IXmlSerializable界面并为IXmlSerializable.WriteXml提供实施,如果XmlSerializer将调用该实施。

这样您就可以将想要的xml直接制作成XmlWriter

如果您还需要反序列化,则还需要为IXmlSerializable.ReadXml提供等效的实现。