Search code examples
c#xmlinheritancedeserialization

How do I deserialize a list of XML tags while keeping class inheritance intact?


I have an XML file that looks a little like this

<Root>
    <People>
        <Person>
            <Name>John</Name>
        </Person>
        <Customer>
            <Name>Johnny</Name>
            <Money>400</Money>
        </Customer>
        <Student>
            <Name>Johnson</Name>
            <GPA>2.5</GPA>
        </Student>
    </People>
</Root>

and some classes that mirror this, using inheritance.

public class Person
{
    public string Name;
}
public class Customer : Person
{
    public int Money;
}
public class Student : Person
{
    public float GPA;
}
public class Root
{
    public List<Person> People;
}

I want to be able to deserialize the XML into a Root instance, keeping the values of Money and GPA intact when the child classes are inserted into the People list. I was hoping for a clean solution with XmlSerializer, but I will take basically anything at this point.

I have tried messing with XmlIncludeAttribute, XmlChoiceIdentifierAttribute, and XmlElementAttribute to varying degrees, but the data in either of the two inherited classes doesn't populate when casting to the child classes (if I can cast at all).

Note: The XML files I am operating on come from a outside source, so editing the XML structure isn't viable.


Solution

  • Works with XmlArrayItemAttribute.

    public class Root
    {
        [XmlArrayItem(typeof(Person), ElementName = "Person")]
        [XmlArrayItem(typeof(Customer), ElementName = "Customer")]
        [XmlArrayItem(typeof(Student), ElementName = "Student")]
        public List<Person> People { get; set; } 
    }
    

    Demo @ .NET Fiddle