Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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; }

[XmlElement("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; }

[XmlElement("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; }

[XmlElement("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.

share|improve this question

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.