Reputation: 303
UPDATE: SOLVED - See below!
When deserializing a xml file containing network nodes there seem to go something wrong when handling child elements.
I've got the following parent (root) class: NetworkCollection
[Serializable, XmlRoot("networks"), XmlType("networks")]
public class NetworkCollection : CollectionBase, IBindingList
{
// ...
}
With the child classes: Network
[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; }
}
Same for NodeCollection and 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; }
}
There are different node types, like this
[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
{
// ...
}
The XML looks like this
<?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>
What happens is that every NodeCollection contains one element, so
Nodes (1),
NodesToAdd (1),
NodesToRemove (1) and
NodesAvailable (1)
all contain one Node object with it's property (MacAddress) set to null;
This should be
Nodes (5),
NodesToAdd (0),
NodesToRemove (0) and
NodesAvailable (4)
Deserializing the NetworkCollection and Network works fine. It's just about the NodeCollection properties.
Please note the used XmlRoot and XmlType attributes. The "Id" of the available nodes might be null / missing.
How to deal with this? Regards
OK, i've solved the problem by replacing
[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; }
With
[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; }
Regards.
Upvotes: 3
Views: 1777
Reputation: 303
OK, i've solved the problem by replacing
[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; }
With
[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; }
Regards.
Upvotes: 2