使用自定义标签名对不同类的数组进行Xml序列化

3
假设我有以下类结构:
[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,是否有可能实现手动创建源xml并使其更具人性化和友好性?

2个回答

9
我找到了一个解决方案,几乎符合您的要求:
  [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>

希望这能有所帮助。

你说得对,如果没有那些XmlInclude属性,我的示例将无法工作。但这并不会改变序列化的输出结果。 - Vladimir Perevalov
谢谢!这正是我需要的。我只是将XmlArrayItem更改为XmlElement,因为我不想在它们周围有一个容器。但无论如何,这很好用。 - Vladimir Perevalov

0

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

如果类型本身不在根处(而是组成另一个类),则会忽略你尝试使用的[XmlRoot]属性。

但是,你可以实现IXmlSerializable接口,并为IXmlSerializable.WriteXml提供实现,如果存在,则XmlSerializer将调用它。

这将允许你直接向XmlWriter编写所需的xml。

如果你还需要反序列化,你还需要提供一个等效的IXmlSerializable.ReadXml实现。


1
这似乎使得使用XmlSerializer的整个想法变得毫无意义。我可以自己编写自定义序列化/反序列化代码。 - Vladimir Perevalov
不是真的 - 想象一下,如果你有一个对象图,其中只有一个对象位于图的中心,而你想要改变它的行为。使用这种方法,您可以保留图中所有其他类型的默认序列化,并仅覆盖需要自定义的那个类型。如果您只编写了大量自定义内容而没有使用“IXmlSerializable”,则必须为图中的每个对象编写自定义实现。 - Rob Levine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接