将XML反序列化为不同元素上的相同类型子元素

时间:2013-06-13 11:01:39

标签: c# .net xml collections deserialization

更新:已解决 - 见下文!

在反序列化包含网络节点的xml文件时,处理子元素时似乎出错了。

我有以下父(root)类:NetworkCollection

[Serializable, XmlRoot("networks"), XmlType("networks")]
public class NetworkCollection : CollectionBase, IBindingList
{
  // ...
}

使用子类:网络

[Serializable, XmlRoot("network"), XmlType("network")]
public class Network
{
    [XmlAttribute("id")]
    public string Id { get; set; }

    [XmlElement("name")]
    public string Name { get; set; }

    // ...

    [XmlElement("nodes")]
    public NodeCollection Nodes { get; set; }

    [XmlElement("to_add")]
    public NodeCollection NodesToAdd { get; set; }

    [XmlElement("to_remove")]
    public NodeCollection NodesToRemove { get; set; }

    [XmlElement("available")]
    public NodeCollection NodesAvailable { get; set; }
}

NodeCollection和Node

相同
[Serializable, XmlRoot("nodes"), XmlType("nodes")]
public class NodeCollection : CollectionBase, IBindingList
{
    // ...
}

[Serializable, XmlRoot("node"), XmlType("node")]
public class Node
{
    [XmlAttribute("id")]
    public string Id { get; set; }

    [XmlElement("mac_address")]
    public string MacAddress { get; set; }
}

有不同的节点类型,例如

[Serializable, XmlRoot("node_type_a"), XmlType("node_type_a")]
public class NodeTypeA : Node
{
    // ...
}

[Serializable, XmlRoot("node_type_b"), XmlType("node_type_b")]
public class NodeTypeB : Node
{
    // ...
}

[Serializable, XmlRoot("node_type_c"), XmlType("node_type_c")]
public class NodeTypeC : Node
{
    // ...
}

XML看起来像这样

<?xml version="1.0" encoding="ISO-8859-1"?>
<networks>
  <network id="bcb468cac8a34052bf5a5bad8f22d0d7">
    <name>Network Name</name>
    <nodes>
      <node_type_a id="0ac4774277a941228b27d8cfd7ef202e">
        <mac_address>AABBCCDDEEFF</mac_address>
      </node_type_b>
      <node_type_a id="4ca5abb4bb8742c3b321250c20592542">
        <mac_address>BBCCDDEEFFAA</mac_address>
      </node_type_a>
      <node_type_b id="bde044c9aa1948978ba1bc980f00c36b">
        <mac_address>CCDDEEFFAABB</mac_address>
      </node_type_b>
      <node_type_c id="d3f2cb7bd92e4dc89930eeb3cdaeb680">
        <mac_address>DDEEFFAABBCC</mac_address>
      </node_type_c>
      <node_type_c id="039d140b5cc54e06b915b91fb5d8acdf">
        <mac_address>EEFFAABBCCDD</mac_address>
      </node_type_c>
    </nodes>
    <to_add/>
    <to_remove/>
    <available>
      <node>
        <mac_address>FFAABBCCDDEE</mac_address>
      </node>
      <node>
        <mac_address>001122334455</mac_address>
      </node>
      <node>
        <mac_address>112233445566</mac_address>
      </node>
      <node>
        <mac_address>223344556677</mac_address>
      </node>
    </available>
  </network>
</networks>

每个NodeCollection都包含一个元素,所以

Nodes (1),
NodesToAdd (1),
NodesToRemove (1) and
NodesAvailable (1)

都包含一个Node对象,其属性(MacAddress)设置为null;

这应该是

Nodes (5),
NodesToAdd (0),
NodesToRemove (0) and
NodesAvailable (4)

反序列化NetworkCollection和网络正常。它只是关于NodeCollection属性。

请注意使用的XmlRoot和XmlType属性。 可用节点的“Id”可能为空/缺失。

如何处理? 此致


好的,我已经通过替换

解决了这个问题
[XmlElement("nodes")]
public NodeCollection Nodes { get; set; }

[XmlElement("to_add")]
public NodeCollection NodesToAdd { get; set; }

[XmlElement("to_remove")]
public NodeCollection NodesToRemove { get; set; }

[XmlElement("available")]
public NodeCollection NodesAvailable { get; set; }

使用

[XmlArray("nodes")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection Nodes { get; set; }

[XmlArray("to_add")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesToAdd { get; set; }

[XmlArray("to_remove")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesToRemove { get; set; }

[XmlArray("available")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesAvailable { get; set; }

问候。

1 个答案:

答案 0 :(得分:2)

好的,我已经通过替换

解决了这个问题
[XmlElement("nodes")]
public NodeCollection Nodes { get; set; }

[XmlElement("to_add")]
public NodeCollection NodesToAdd { get; set; }

[XmlElement("to_remove")]
public NodeCollection NodesToRemove { get; set; }

[XmlElement("available")]
public NodeCollection NodesAvailable { get; set; }

使用

[XmlArray("nodes")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection Nodes { get; set; }

[XmlArray("to_add")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesToAdd { get; set; }

[XmlArray("to_remove")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesToRemove { get; set; }

[XmlArray("available")]
[XmlArrayItem(ElementName = "node", Type = typeof(Node))]
[XmlArrayItem(ElementName = "node_type_a", Type = typeof(NodeTypeA))]
[XmlArrayItem(ElementName = "node_type_b", Type = typeof(NodeTypeB))]
[XmlArrayItem(ElementName = "node_type_c", Type = typeof(NodeTypeC))]
public NodeCollection NodesAvailable { get; set; }

问候。