I have a legacy system that uses some data that is stored in XML format. The format of the XML cannot be changed without causing critical issues (i.e. tooling and other software that reads the format).
The XML is structured like this:
<Things>
<ThingOne Name="FirstThing">
<ThingOne Name="FirstChildThing" />
<ThingTwo Name="SecondChildThing"/>
</ThingOne>
<ThingTwo Name="SecondThing">
<ThingOne Name="ThirdChildThing" />
<ThingTwo Name="FourthChildThing" />
</ThingTwo>
</Things>
In my scenario "ThingOne" and "ThingTwo" are classes that extend "SomeThing". Like this:
public abstract class SomeThing
{
public int ItemNumber {get; set;}
public string Name {get; set;}
public List<SomeThing> ChildThings {get; set;}
public abstract void InspectChildren();
}
public sealed class ThingOne : SomeThing
{
public override void InspectChildren()
{
/*Iterates Child Things and performs actions*/
}
}
public sealed class ThingTwo : SomeThing
{
public override void InspectChildren()
{
/*Iterates Child Things and performs actions different from thing one*/
}
}
And "Things" is a class with a collection of "SomeThing":
public sealed class Things
{
/*Thing One and Thing Two should be deserialized to here*/
public List<SomeThing> ThingItems {get; set;}
}
There is a thing inspector like this:
public static ThingInspector
{
public static void InspectThings(IEnumerable<SomeThing> thingsToInspect)
{
foreach(var thing in thingsToInspect)
{
thing.InspectChildren()
}
}
}
However when I use the XmlSerializer to deserialize the XML into an instance of "Things" it doesn't pickup "ThingOne" and "ThingTwo" and add them into ThingItems.
I have tried decorating the classes as follows:
public sealed class Things:IList<SomeThing>
{
/*Thing One and Thing Two should be deserialized to here*/
[XmlArrayItem(typeof(ThingOne), ElementName = "ThingOne")]
[XmlArrayItem(typeof(ThingTwo), ElementName = "ThingTwo")]
public List<SomeThing> ThingItems {get; set;}
/*Example doesn't include IList implementation, but it is present and correct*/
}
public abstract class SomeThing
{
[XmlIgnore]
public int ItemNumber {get; set;}
[XmlAttribute]
public string Name {get; set;}
[XmlArrayItem(typeof(ThingOne), ElementName = "ThingOne")]
[XmlArrayItem(typeof(ThingTwo), ElementName = "ThingTwo")]
public List<SomeThing> ChildThings {get; set;}
public abstract void InspectChildren();
}
The deserialized object is an instance of "Things", but ThingItems is empty.
What am I missing? I have tried changing the xml format so that "ThingOne" and "ThingTwo" are wrapped in a "ThingItems" list and that works fine, but the xml format in the production system cannot be changed without causing failures with other software that is reading and writing the xml data.
My problem is that I need to deserialize the child elements of "Things" into a list on the corresponding "Things" class instead of forcing the object structure onto the XML. Any guidance would be appreciated.