Tips & Tricks: Use XDocument.Load() for XML Handling

Handling XML documents within an application is sometimes tricky, even trickier when parsing XML documents in memory. This is just an example how to handle XML documents in memory. Let’s say there is an XML document looking like this:

<Products>
  <Product>
    <Id>1</Id>
    <Name>My Product</Name>
    <Price>9.99</Price>
  </Product>
</Products>
`</pre>

This is a typical XML document. Now, try to import this document into memory for handling. The code might look like:

<pre>`using (var stream = new FileStream("product.xml"))
using (var reader = new StreamReader(stream))
{
    var xml = reader.ReadToEnd();
}
`</pre>

There's no problem at all. Even if you put additional line after the `var xml...` line like:

<pre>`File.WriteAllText("result.xml", xml);

`</pre>

Once the app runs, you can see the `result.xml` file without an issue. However, when you try to deserialise the parsed XML string into a designated object type, this will be an issue. You can't do like this:

<pre>`using (var stream = new FileStream("product.xml"))
{
    var serialiser = new XmlSerializer(typeof(Products));
    var result = (Products)serialiser.Deserialize(stream);
}
`</pre>

Nor, you can't do this:

<pre>`using (var stream = new FileStream("product.xml"))
using (var reader = new StreamReader(stream))
{
    var serialiser = new XmlSerializer(typeof(Products));
    var result = (Products)serialiser.Deserialize(reader);
}
`</pre>

This won't be happening, either:

<pre>`using (var stream = new FileStream("product.xml"))
using (var reader = new StreamReader(stream))
{
    var xml = reader.ReadToEnd();
    using (var sr = new StringReader(xml))
    {
        var serialiser = new XmlSerializer(typeof(Products));
        var result = (Products)serialiser.Deserialize(reader);
    }
}
`</pre>

If you put a break point on the `var xml...` line and run a debug mode, you will see the `xml` value looks like:

<pre>`&lt;\0P\0r\o\0d\0u\0c\0t\0s&gt;...
`</pre>

This causes the XML parsing error. It won't be an issue when you directly store the parsed XML value into a file, but will raise an error when deserislising it into an object. Hence instead, you should do like:

<pre>`using (var stream = new FileStream("product.xml"))
{
    var xml = XDocument.Load(stream);
    using (var reader = new StringReader(xml.ToString()))
    {
        var serialiser = new XmlSerializer(typeof(Products));
        var message = XmlUtils.XmlDeserialize&lt;QueueMessage&gt;(reader);
    }
}

Actually, as long as the StringReader object can read proper string values, it should be fine. But reading values directly from Stream object causes an issue. At least the value should be loaded by either XmlDocument or XDocument for deserialisation.

HTH. Happy Coding!