Background: I have a simple XML sheet, which i cannot change, this is supplied by a 3rd party, The class and deserialization is maintained by us
Question How do i get the xml to deserialize properly, it obviously needs to somehow check the "name" attribute to decide which property to fill, but for the life of me i can not remember how to do this. The current serializer we are using is 'System.Xml.Serialization.XmlSerializer' and due to legacy, dependent code we can not change this.
XML
<result>
<rowset name="divisions" key="accountKey" columns="accountKey,description">
<row accountKey="1000" description="Division 1"/>
<row accountKey="1001" description="Division 2"/>
<row accountKey="1002" description="Division 3"/>
<row accountKey="1003" description="Division 4"/>
<row accountKey="1004" description="Division 5"/>
<row accountKey="1005" description="Division 6"/>
<row accountKey="1006" description="Division 7"/>
</rowset>
<rowset name="walletDivisions" key="accountKey" columns="accountKey,description">
<row accountKey="1000" description="Wallet Division 1"/>
<row accountKey="1001" description="Wallet Division 2"/>
<row accountKey="1002" description="Wallet Division 3"/>
<row accountKey="1003" description="Wallet Division 4"/>
<row accountKey="1004" description="Wallet Division 5"/>
<row accountKey="1005" description="Wallet Division 6"/>
<row accountKey="1006" description="Wallet Division 7"/>
</rowset>
</result>
Class
[Serializable]
[XmlRoot("result", IsNullable = false)]
public class TestClass
{
[XmlElement("rowset")]
public EveXmlRowCollection<Division> Divisions { get; set; }
[XmlElement("rowset")]
public EveXmlRowCollection<Division> WalletDivisions { get; set; }
[Serializable]
[XmlRoot("row")]
public class Division
{
[XmlAttribute("accountKey")]
public int AccountKey { get; set; }
[XmlAttribute("description")]
public string Description { get; set; }
}
}
public class EveXmlRowCollection<T> : Collection<T>, IXmlSerializable
{
//... Other, Irrelevant implementations
public void ReadXml(XmlReader reader) {
var serializer = new XmlSerializer(typeof (T));
if (!reader.IsStartElement()) return;
RowSetMeta.Name = reader.GetAttribute("name");
RowSetMeta.Key = reader.GetAttribute("key");
RowSetMeta.Columns = reader.GetAttribute("columns");
reader.ReadToDescendant("row");
while (reader.Name == "row") {
if (reader.IsStartElement()) {
var row = (T) serializer.Deserialize(reader);
Items.Add(row);
}
reader.ReadToNextSibling("row");
}
}
}
What about doing it in two steps? First you can deserialize xml without any logic. Just create appropriate models:
Using them deserilizing is very trivial:
And then you can create needed models using C# power:
And you will return
DeserializedAndNormilizedObject
as a result of deserialization.