You all know what XML is, but for most people they don't know how to use XML in the most efficient way. Since we are dealing with XML more and more and larger sizes of it each time, it was about time to ensure that we optimize how we use the XML library in .NET. I'm not going to get into designing of XML as that can be done in a later how to. What this talk is going to be about is what XML objects to use given the situation and why.

For the most part there comes down to 4 basic objects that you will have to decide between when using XML.

  • System.Xml.XmlReader this pull model XML parsers, such as the XmlReader, operate in a forward only, streaming fashion while only showing information about a single node at any given time. This doesn't require the entire document to be loaded. If performance is your highest priority but you don't require XSD validation, XSD type information (i.e. Named Properties) and you don't need XSLT use this.
  • System.Xml.XPath.XPathNavigator this is used in conjunction with XPathDocument most of the time but doesn't have to be. This also doesn't require the entire document to be loaded. If you require XSLT and read only. You can read the XML in any direction at any time.
  • System.Xml.XmlDocument this is a DOM (Document Object Model) representation of the XML data. This requires the entire XML document to be loaded. This method is used if you are looking to read/write to the XML.
  • System.LINQ the newest and most friendly way to query an XML document if LINQ. It provides robust ways to query for data, easy and understandable logic and Language Integrated Queries.

Now saying these objects will probably remind you of how use used one of these and what purpose you used it for. There are certain situations that it are more suited for each object above. Yes you can use any of the objects and they will solve what you're doing but possibly done better with another.

System.Xml.XmlReader

Where should you use XmlReader?

Methods is a prime example on when to use XmlReader. When passing in XML you have to choose what you're going to do with it. If you're just looking at reading the XML or passing it off to the next layer then you should be using XmlReader or XPathNavigator.


   
      16.95
      Nelly
      Nellyville
   
   
      17.55
      Baby D
      Lil Chopper Toy
   

 public static void PrintArtistAndPrice(XmlReader reader)
 {
    reader.MoveToContent();
    while(reader.Read())
    {
       if((reader.NodeType == XmlNodeType.Element) && reader.Name.Equals("artist"))
       {
          artist = reader.ReadElementString();
          title  = reader.ReadElementString();
          break;
       }
    }
    Console.WriteLine("Artist={0}, Title={1}", artist, title);
 }

As with the same for return types, if you know the XML will be edited then return XmlDocument otherwise return XmlReader or XPathNavigator (depending on if the data will require streaming or forward-only access).

System.Xml.XPathNavigator

Where to use XPathNavigator?

As with XmlReader you'll want to use XPathNavigator when dealing with methods. In keeping with the same example above you can see how to use XPathNavigator.

 public static void PrintArtistAndPrice(XPathNavigator nav)
 {
    XPathNodeIterator iterate = nav.Select("/items/compact-disc[1]/artist/items/compact-disc[1]/title");
    iterator.MoveNext();
    Console.WriteLine("Artist={0}", iterator.Current);
    iterator.MoveNext();
    Console.WriteLine("Title={0}", iterator.Current);
 }

So why use XPathNavigator over XmlReader? The biggest reason is for XPath support as well as being able to iterate through the document in multiple directions.

System.Xml.XmlDocument

Where to use XmlDocument?

XmlDocument is used primarily for reading/writing to an Xml file. If you are looking to write back to a file or need the document validated for consistency this is what you want to use. XmlDocument will only load the entire document unlike the other readers that will load partial files up to an error. XmlDocument also supports XPath navigation which allows for quick navigation to any given element at any time. This is the most used Xml type object, but can be the most expensive in memory but is often overlooked because of it's productivity and ease of use.

Generating XML

Majority of the time you could use XmlSerializer but in some cases you want to control the namespaces and structure so you can use XmlDocument. If you want to write Xml to an XmlDocument you should use XmlNodeWriter.

XSLT Transformation

private void Load_Document()
{
   System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
   doc.Load(Server.MapPath("MySource.Xml"));
   System.Xml.Xsl.XslTransform trans = newSystem.Xml.Xsl.XslTransform();
   trans.Load(Server.MapPath("MyStyle.xsl"));
   Xml1.Document = doc;
   Xml1.Transform = trans;
}
XPath


   
      Beginning XML
      Wrox
   
   
      XML Step by Step
      MSPress
   
   
      Professional XML
      Wrox
   
   
      Developing XML solutions
      MSPress
   

System.Xml.XmlDocument Xmldoc = new System.Xml.XmlDocument();
Xmldoc.Load("C:\\books.Xml");
System.Xml.XmlNodeList MSPressBookList = Xmldoc.SelectNodes("//Publisher[. = 'MSPress']/parent::node()/Title");
foreach (System.Xml.XmlNode MSPressBook in MSPressBookList)
{
   System.Diagnostics.Debug.WriteLine(MSPressBook.InnerText);
}
System.Xml.XmlNode bookNode = Xmldoc.SelectSingleNode("//Title[.='XML Step by Step']");
if (!(bookNode == null))
{
   System.Diagnostics.Debug.WriteLine("Located title 'XML Step by Step'");
}
else
{
   System.Diagnostics.Debug.WriteLine("Could not locate title 'XML Step by Step'");
}

System.LINQ

The great thing about LINQ is everyone usually knows it, they might not know every trick or the exact syntax but it follows the structure of SQL. The ability to use LINQ on Xml files allows you to have more transparent queries which can be used on a more range of Xml files. The biggest advantage of using LINQ to query your Xml is Language Integrated Query. LINQ also allows for the return type to be Enumerable which allows you to put a foreach or while loop with better object representation.


   
      Patrick Hines
      206-555-0144
      425-555-0145
      
WA
Gretchen Rivas
WA
Scott MacDonald 925-555-0134 425-555-0177
CA
XElement contactsFromFile = XElement.Load(@"c:\myContactList.xml");
foreach (XElement x in contactsFromFile.Elements("contact").Elements())
{
   Console.WriteLine(x);
}
XElement contacts = new XElement("contacts",
   from c in contactsFromFile.Elements("contact")
   select new XElement("contact", c.Element("name"),
      c.Element("phone")));
static XElement GetPhoneNumbers(XElement c)
{
   if (c.Elements("phone").Any())
   {
      return new XElement("phoneNumbers", c.Elements("phone"));
   }
   else
   {
      return null;
   }
}
contactsFromFile.Descendants("phone").Attributes("type").Select(t => t.Value).Distinct();

Recommendations

  • When returning Xml Data return an XmlReader
  • Use LINQ to Xml with basically everything else as it gives you the same robustness but it's light weight compared to XmlDocument and more OO then XPath