2

I have an XML file with the following format:

<?xml version="1.0" encoding="UTF-8"?>
<Items>
    <Item Property1="A" Property2="B" />
    <Item Property1="C" Property2="D" />
</Items>

I need to read the <Item> elements as objects of class MyClass using an XmlSerializer.

public class MyCLass
{
    [XmlAttribute]
    public string Property1 { get; set; }

    [XmlAttribute]
    public string Property2 { get; set; }
}

Currently, I have the following code to read the file:

XmlSerializer serializer =
    new XmlSerializer(typeof(MyClass[]), new XmlRootAttribute(@"Items"));

MyClass[] list = (MyClass[])serializer.Deserialize(...);

Since the element name <Item> is different from the class name MyCLass, the elements in the array are not deserialized at all. The above code works if I rename MyClass to Item, but unfortunately I am not allowed to change the XML file or the class names.

How do I go about mapping the two so that the file can be read correctly?

Thanks in advance!

2 Answers 2

4

Use a wrapper class that contains the array, this will allow you to apply the XmlElement attribute:

public class MyClassList
{
    [XmlElement("Item")]
    public MyClass[] Items { get; set; }
}

var items = new[]
{
    new MyClass { Property1 = "A", Property2 = "B" },
    new MyClass { Property1 = "C", Property2 = "D" },
};
var list = new MyClassList { Items = items };

using (var writer = new StringWriter())
{
    var xs = new XmlSerializer(typeof(MyClassList), new XmlRootAttribute("Items"));
    xs.Serialize(writer, list);
    writer.ToString().Dump();
}
Sign up to request clarification or add additional context in comments.

1 Comment

I'm not so sure why it works though :-) I was running around after XmlArrayItem and XmlAttributeOverrides. Thanks again!
2

Personally I would serialize and deserialize manually - I've found that it's easier to get whatever flexibility you want that way rather than spending a long time messing around with the built-in serialization and living with the various restrictions it imposes. LINQ to XML makes it pretty simple. For example, in this case:

XDocument doc = XDocument.Load("test.xml");
// You could use an array if you really wanted, of course.
List<MyClass> list = doc.Root
                        .Elements("Item")
                        .Select(x => new MyClass {
                            Property1 = (string) x.Attribute("Property1"),
                            Property2 = (string) x.Attribute("Property2"),
                         })
                        .ToList();

Admittedly this will get hairy if you need to serialize objects with complicated relationships (two objects referring to the same child or whatever) but I've had a great deal of success with it in the past.

2 Comments

Thanks for the tip! In my case, the actual MyClass structure is pretty complex, with nested hierarchies - so this approach could get a bit complicated...
@xmlWiz: If you follow a pattern with each class knowing how to deserialize and serialize itself, I've found it's not too bad - and easy to unit test. But if you have shared references etc, it does get complicated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.