GSharper

Tuesday 12 June 2007

Deserialize XML file to an Domain object

Some time ago, I read this article on how to deserialize XML files into objects and I thought, let's give this a try. Let's try a simple domain class Person which has a couple of properties like FirstName, LastName and an Address List for which I created another domain class.

I started with the XML file

<?xml version="1.0" encoding="utf-8" ?>
<Persons xmlns="http://personreader" DefaultProfile="XmlToObjectDeserialization">
<PersonInfo AssemblyFile="Domain.dll" >
<FirstName>John</FirstName>
<LastName>Doe</LastName>
<Address>
<StreetName>Hit the road street</StreetName>
<HouseNumber>6</HouseNumber>
<PostalCode>5800B</PostalCode>
<Location>New York</Location>
</Address>
<Address>
<StreetName>Secondary Address Street</StreetName>
<HouseNumber>44</HouseNumber>
<PostalCode>1500</PostalCode>
<Location>California</Location>
</Address>
</PersonInfo>
</Persons>


The next thing to do, is create the domain classes. These classes have to reflect the XML file's properties. We start with the Person class:


namespace Domain
{
[XmlRoot(
"Persons",Namespace="http://personreader")]
public class Persons
{
// Return array of PersonInfo objects
[XmlElement("PersonInfo")]
public PersonInfo[] PersonInfos;
}
}

Notice the Namespace property in the attribute. It has to be the same as the xmlns attribute in the XML file. We define a Person class with a list of PersonInfo objects. This PersonInfo class looks like this:



namespace Domain
{
public class PersonInfo
{
// Match properties of XML file
[XmlAttribute]
public string AssemblyFile;

[XmlElement(
"FirstName")]
public string FirstName;

[XmlElement(
"LastName")]
public string LastName;

[XmlElement(
"Address")]
public Address[] Address;
}
}


The AssemblyFile string is marked as an XmlAttribute. All the others are XmlElements which corresponds with the XML file.


Finally, the Address class:



namespace Domain
{
public class Address
{
[XmlElement(
"StreetName")]
public string StreetName;

[XmlElement(
"HouseNumber")]
public string HouseNumber;

[XmlElement(
"PostalCode")]
public string PostalCode;

[XmlElement(
"Location")]
public string Location;
}
}
Clearly no rocket science here.


The only thing that has to be done is the deserialization of course. It works like this:



private static void DeserializeXml()
{
using (TextReader tr =
File.OpenText(
@"PersonsData.xml"))
{
XmlSerializer serializer
=
new XmlSerializer(typeof(Persons));

Persons persons
=
(Persons)serializer.Deserialize(tr);
}
}


Not that difficult. We open our file and put the content into a stream. Then we create a XmlSerializer and let it know that we want to deserialize to the Persons domain class.


Finally deserialize the stream and we're done.


Greetz,                                                                              G