<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vidar's Musings &#187; deserialization</title>
	<atom:link href="http://www.kongsli.net/nblog/tag/deserialization/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kongsli.net/nblog</link>
	<description>Deep thoughts on shallow topics</description>
	<lastBuildDate>Fri, 27 Jan 2012 07:36:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Parsing XML using XmlSerializer or DataContractSerializer</title>
		<link>http://www.kongsli.net/nblog/2010/02/01/parsing-xml-using-xmlserializer-or-datacontractserializer/</link>
		<comments>http://www.kongsli.net/nblog/2010/02/01/parsing-xml-using-xmlserializer-or-datacontractserializer/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 11:15:00 +0000</pubDate>
		<dc:creator>vidarkongsli</dc:creator>
				<category><![CDATA[Microsoft technologies]]></category>
		<category><![CDATA[Software development]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[deserialization]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[wcf]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.kongsli.net/nblog/?p=154</guid>
		<description><![CDATA[If you want to parse XML in .NET, you have a lot of options to choose from. You can use XmlDocument to parse the XML into a DOM tree, you can use the XmlReader to write an efficient &#8220;pull&#8221; parser, or you can leverage some of the features provided with various serialization APIs. Given the [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to parse XML in .NET, you have a lot of options to choose from. You can use XmlDocument to parse the XML into a DOM tree, you can use the XmlReader to write an efficient &#8220;pull&#8221; parser, or you can leverage some of the features provided with various serialization APIs.</p>

<p>Given the case where you have a fairly straightforward XML document (not too deep document tree, not too complex set of attributes and elements) that maps pretty well to your domain model, the serialization options is in my mind a good choice that requires little coding. Compared with this approach, using XmlDocument seems to be a bit of an overkill if you don&#8217;t need advanced traversal of the document, and writing a parser by hand using XmlReader seems to require quite a bit of coding.</p>

<p>So, given the following sample XML document, I will investigate the serialization options:
<pre class="xml" name="code">&lt;countries&gt;
   &lt;country&gt;
      &lt;iso-3166-alpha-2-code&gt;AF&lt;/iso-3166-alpha-2-code&gt;
      &lt;name&gt;Afghanistan&lt;/name&gt;
   &lt;/country&gt;
   &lt;country&gt;
      &lt;iso-3166-alpha-2-code&gt;AX&lt;/iso-3166-alpha-2-code&gt;
      &lt;name&gt;Åland Islands&lt;/name&gt;
   &lt;/country&gt;
   &lt;country&gt;
      &lt;iso-3166-alpha-2-code&gt;AL&lt;/iso-3166-alpha-2-code&gt;
      &lt;name&gt;Albania&lt;/name&gt;
   &lt;/country&gt;
&lt;/countries&gt;</pre></p>

<h4>Using System.Xml.XmlSerializer</h4>

<p>The first option that came to mind, was to use the XmlSerializer object to deserialize the XML into C# (or VB for that matter) objects. It first requires that I annotate my object model in order to tell the serializer how to deserialize the XML:</p>

<p><pre class="c-sharp" name="code">
[XmlRoot("countries")]
public class Countries
{
   [XmlElement(ElementName="country")]
   public Country[] countries;
}</pre></p>

<p>public class Country
{
   [XmlElement(ElementName = "name")]
   public string Name;</p>

<p>[XmlElement(ElementName = "iso-3166-alpha-2-code")]
   public string Code;
}

Then, I can use the serializer to deserialize the code:
<pre class="c-sharp" name="code">
string xml = ...;</pre></p>

<p>XmlSerializer xmlSerializer = new XmlSerializer(typeof(Countries));
Countries c = xmlSerializer.Deserialize(new StringReader(xml)) as Countries;

Pretty sweet,  heh? Definitely. However, this has some drawbacks. If I want my Country class to be a well designed domain object that follows good OO design principles, I probably would like to encapsulate my data. Furthermore, I might want to restrict the creation of such objects from other parts of the code. In order for XmlSerializer to create my object, it requires that my types are public and that all properties or fields to set are public as well. What to do if I want to enforce my objects to be immutable once handed off to other parts of the code?</p>

<h4>Using System.Runtime.Serialization.DataContractSerializer</h4>

<p>Luckily, the serialization API that come with Windows Communication Framework has some neat features that fit like a glove. When defining my data model, it does not require that the types, neither the properties nor fields to set are public. Actually, I can restrict access to the type, its default constructor, and any of the properties or fields that I want to be deserialized! w00t!</p>

<p>So, this is what the Country class will looks like:
<pre class="c-sharp" name="code">
[DataContract(Name="country", Namespace="")]
internal class Country : IExtensibleDataObject
{
   private Country() { }</pre></p>

<p>[DataMember(Name="name")]
   public string Name { get; private set; }</p>

<p>[DataMember(Name = "iso-3166-alpha-2-code")]
   public string Code { get; private set; }</p>

<p>public ExtensionDataObject ExtensionData { get; set; }
}

The XML file contains a list of countries, and luckily, we have the CollectionDataContractAttribute to denote an element that is a list of elements. It supports generics, so that we can define our class as a strongly typed list:
<pre class="c-sharp" name="code">
[CollectionDataContract(Name="countries", Namespace="")]
internal class Countries : List&lt;Country&gt;, IExtensibleDataObject
{
   public ExtensionDataObject ExtensionData { get; set; }
}
</pre>
And that&#8217;s it. Now we can deserialize:
<pre class="c-sharp" name="code">
string xml = ...;</pre></p>

<p>DataContractSerializer ser = new DataContractSerializer(typeof(Countries));
using (StringReader stringReader = new StringReader(xml))
{
   using (XmlReader xmlReader = XmlReader.Create(stringReader))
   {
      Countries countries = (Countries)ser.ReadObject(xmlReader);
   }
}

Alternatively, our result could be typed as a list of countries:
<pre class="c-sharp" name="code">
IList&lt;Country&gt; countries = (IList&lt;Country&gt;)ser.ReadObject(xmlReader);
</pre>
Note that there is a limitation in the latter method in that deserializing XML attributes is not supported. Thus, an XML document like the following would not work:
<pre class="c-sharp" name="code">
   &lt;country iso-3166-alpha-2-code="AF"&gt;
      &lt;name&gt;Afghanistan&lt;/name&gt;
   &lt;/country&gt;
   &lt;country iso-3166-alpha-2-code="AX"&gt;
      &lt;name&gt;Åland Islands&lt;/name&gt;
   &lt;/country&gt;
   &lt;country iso-3166-alpha-2-code="AL"&gt;
      &lt;name&gt;Albania&lt;/name&gt;
   &lt;/country&gt;
&lt;/countries&gt;
</pre>
This will, however, work using the XmlSerializer.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.kongsli.net%2Fnblog%2F2010%2F02%2F01%2Fparsing-xml-using-xmlserializer-or-datacontractserializer%2F&amp;title=Parsing%20XML%20using%20XmlSerializer%20or%20DataContractSerializer" id="wpa2a_2"><img src="http://www.kongsli.net/nblog/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.kongsli.net/nblog/2010/02/01/parsing-xml-using-xmlserializer-or-datacontractserializer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

