XmlDocument versus XDocument versus XmlReader/XmlWriter

With AspNet, there are three possible paths to handling XML. There is a nice performance comparison done by Joe Ferner which augments many earlier studies between XmlDocument and XmlReader/XmlWriter. The use of XmlDocument  could be justified for quick and dirty prototyping because:

  • It is often the fastest to code and debug
  • It is suitable for neophytes to Xml

For anything that is production --- forget XmlDocument!!!  It is a memory hog and slow!

A quote in the article states it all “It is not surprising the XmlReader code is faster since both the XML DOM (XmlDocument) and LINQ to XML use XmlReader to do their reading.”

 

So if any volume of Xml is used, there is no rationale choice except for XmlReader/XmlWriter. I have processed gigabyte Xml files with these and have not seen memory usage go over 200K; on the other hand, I have max memory out with XmlDocument.

 

So for small pieces of data what do you use?  Coding and reading XmlReader/XmlWriter code is a lot more effort than XDocument, so I am inclined to advocate XDocument. To illustrate this consider this code that transfer data from an IEnumerable (Data bound control) to XML for persisting in a view state:

protected override void PerformDataBinding(IEnumerable retrievedData)
{
    base.PerformDataBinding(retrievedData);
    if (retrievedData != null)
    {
        XElement root = new XElement("data");
        XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), root);
        foreach (object dataItem in retrievedData)
        {
            root.Add(new XElement("hyperlink",
                new XAttribute("CssClass", dataItem.GetProperty(DataCssClassField, CssClass)?? String.Empty),
                new XAttribute("Target", dataItem.GetProperty(DataCssClassField, Target) ?? String.Empty),
                new XAttribute("Text", HttpContext.ResourceTranslation.TranslateField(dataItem.GetProperty(DataTextField, String.Empty))),
                new XAttribute("NavigateUrl", dataItem.GetProperty(DataNavigateUrlField, string.Empty) ?? String.Empty),
                new XAttribute("ImageUrl", dataItem.GetProperty(DataImageUrlField, ImageUrl) ?? String.Empty),
                new XAttribute("ToolTip", HttpContext.ResourceTranslation.TranslateField(dataItem.GetProperty(DataToolTipField, ToolTip)) ?? String.Empty) ));                    
        }
        ViewState.Add("data", doc.ToString());
    }
}

This code can be done also with the following code:

protected override void PerformDataBinding(IEnumerable retrievedData)
{
    base.PerformDataBinding(retrievedData);
    if (retrievedData != null)
    {
        using (var swriter = new StringWriter())
        {
            using (var xwriter = new XmlTextWriter(swriter) { Formatting = Formatting.Indented })
            {
                xwriter.WriteStartDocument(true);
                xwriter.WriteStartElement("data");
                foreach (object dataItem in retrievedData)
                {
                    xwriter.WriteStartElement("hyperlink");
                    xwriter.WriteAttributeString("CssClass", dataItem.GetProperty(DataCssClassField, CssClass) ?? String.Empty);
                    xwriter.WriteAttributeString("Target", dataItem.GetProperty(DataCssClassField, Target) ?? String.Empty);
                    xwriter.WriteAttributeString("Text", HttpContext.ResourceTranslation.TranslateField(dataItem.GetProperty(DataTextField, String.Empty)));
                    xwriter.WriteAttributeString("NavigateUrl", dataItem.GetProperty(DataNavigateUrlField, string.Empty) ?? String.Empty);
                    xwriter.WriteAttributeString("ImageUrl", dataItem.GetProperty(DataImageUrlField, ImageUrl) ?? String.Empty);
                    xwriter.WriteAttributeString("ToolTip", HttpContext.ResourceTranslation.TranslateField(dataItem.GetProperty(DataToolTipField, ToolTip)) ?? String.Empty);
                    xwriter.WriteEndElement();
                }
                xwriter.WriteEndElement();
                xwriter.WriteEndDocument();
            }
            ViewState.Add("data",swriter.ToString());
        }               
    }
}

The code is slightly more complex with XmlReader\XmlWriter, but it has the advantage of being:

  • up to 3x faster than XDocument
  • up to 7x faster than XmlDocument
  • consumes a low finite amount of memory
    • unlike XmlDocument which explodes!
    • unlike XDocument which explodes less…

XDocument coding is nice to rough out things in a way that makes it easy to convert to XmlReader/XmlWriter (as illustrated above).

Comments

Popular posts from this blog

Simple WP7 Mango App for Background Tasks, Toast, and Tiles: Code Explanation

Yet once more into the breech (of altered programming logic)

Error : /ScriptResource.axd : Invalid viewstate.