Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to de-serialize XML with many child nodes

If my XML is like this:

<Item>
    <Name>Jerry</Name>
    <Array>
        <Item>
            <Name>Joe</Name>
        </Item>
        <Item>
            <Name>Sam</Name>
        </Item>
    </Array>
</Item>

I can serialize it into this class:

[DataContract(Namespace = "", Name = "dict")]
public class Item
{
    [DataMember(Name = "Name")]
    public string Name { get; set; }
    [DataMember(Name = "Array")]
    public IEnumerable<Item> Children { get; set; }
}

But what if my XML is like this?

<Item>
    <Name>Jerry</Name>
    <Item>
        <Name>Joe</Name>
    </Item>
    <Item>
        <Name>Sam</Name>
    </Item>
</Item>

This does not work:

[DataContract(Namespace = "", Name = "Item")]
public class Item
{
    [DataMember(Name = "Name")]
    public string Name { get; set; }
    [DataMember(Name = "Item")]
    public IEnumerable<Item> Children { get; set; }
}

What is the right way to decorate the class?

like image 781
Jerry Nixon Avatar asked Nov 21 '11 22:11

Jerry Nixon


People also ask

What is the correct way of using XML deserialization?

To deserialize the objects, call the Deserialize method with the FileStream as an argument. The deserialized object must be cast to an object variable of type PurchaseOrder . The code then reads the values of the deserialized PurchaseOrder .

Which class should be used to serialise an object in XML format?

Xml. Serialization namespace) class is used to serialize and deserialize. The class method Serialize is called. Since we have to serialize in a file, we create a " TextWriter ".

Can I make XmlSerializer ignore the namespace on Deserialization?

Yes, you can tell the XmlSerializer to ignore namespaces during de-serialization.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application.


1 Answers

If you want control over xml, then XmlSerializer is the way to go, not DataContractSerializer. The latter simply lacks the fine-grained control that XmlSerializer offers; in this case for things like list/array layout - but even just xml attributes are a problem for DataContractSerializer. Then it is just:

public class Item {
    public string Name { get; set; }
    [XmlElement("Item")]
    public List<Item> Children { get; set; }
}
public class Item {
    public string Name { get; set; }
}

and:

var serializer = new XmlSerializer(typeof(Item));
var item = (Item) serializer.Deserialize(source);
like image 62
Marc Gravell Avatar answered Sep 21 '22 18:09

Marc Gravell