If your XML is not compatible with the .net XML serialisation, then the easiest way is to create a factory which detects which type of resource the XML represents, then handles that appropriately. If you want to put the parsing into your objects, then use a virtual method to parse the internals after creating the object:
class CarResource
{
public string Color { get; private set; }
internal virtual void ReadFrom(XmlReader xml)
{
this.Color = xml.GetAttribute("colour");
}
}
class RaceCarResource : CarResource
{
public string Sponsor { get; private set; }
internal override void ReadFrom(XmlReader xml)
{
base.ReadFrom(xml);
this.Sponsor = xml.GetAttribute("name-on-adverts");
}
}
class SuperDuperUltraRaceCarResource : RaceCarResource
{
public string Super { get; private set; }
internal override void ReadFrom(XmlReader xml)
{
base.ReadFrom(xml);
this.Super = xml.GetAttribute("soup");
}
}
class CarResourceFactory
{
public CarResource Read(XmlReader xml)
{
CarResource car;
switch (xml.LocalName)
{
case "ordinary-car": car = new CarResource(); break;
case "racecar": car = new RaceCarResource(); break;
case "super_duper": car = new SuperDuperUltraRaceCarResource(); break;
default: throw new XmlException();
}
XmlReader sub = xml.ReadSubtree();
car.ReadFrom(sub);
sub.Close();
return car;
}
}
This works OK if the XML for a sub-type has any child elements appended strictly after or before the content for the super-type. Otherwise you have to do more work to reuse the super-type's serialisation, breaking it up into smaller methods (eg the base has methods to load the number of wheels, doors, engine size; the race car calls LoadDoorData
, LoadAeroFoilData
, LoadWheelData
if the XML for the race car has the aerofoil data in between the door and wheel data. For formats with no logical ordering imposed (XMI, RDF) you have to inspect the local name to decide which specialised method to call, which gets a bit messy if you want to combine it with virtual methods. In that case, it's better to use a separate serialisation helper.
Other mechanisms can be used in the factory if the set of types to be created is not fixed to a few types.