Wordsmyth's Corner

How to Find XML Nodes

Explains how to find data in an XML tree. There appear to be a million ways to do this in .NET. Here are some ways to fit various situations.

XML Reader

The XMLReader class is good for navigating simple nodes in order.

Sample tree:

<Config configured="3" IPAddress="192.168.1.1"></Config >
Sample code using XMLReader:
public void Unpack(string dataString)
   {

   // Convert from string to data stream, which is what the reader expects.

   byte[] bytes = Encoding.UTF8.GetBytes(dataString);
   MemoryStream memStream = new MemoryStream(bytes);
   XmlReader reader = XmlReader.Create(memStream);
   
   // Go through the XML until we reach the the expected elements
   
   while (reader.Read())
      {
      if (reader.NodeType == XmlNodeType.Element &&
          reader.Name == "Config")
         {
         
         // Process the attributes
         
         while (reader.MoveToNextAttribute())
            {
            switch (reader.Name)
               {
               case "configured":
                  m_isConfigured = bool.Parse(reader.Value);
                  break;
               case "IPAddress":
                  m_IPAddress = IPAddress.Parse(reader.Value);
                  break;
               }
            }
         
         }
      }
   }

XPath

The XPath class is good when you want to look up nested nodes, or jump around in the XML without necessarily parsing everything in order.

Sample tree:

<locale>
   <phrases>
      <phrase name="PH_HELLO">Hello</phrase>
      <phrase name="PH_GOODBYE">Goodbye</phrase>
      ...
   </phrases>
</locale>
Sample code (using XPath):
 
public string GetPhrase(string name)
   {

   XMLDocument resourceFile = new XMLDocument;
   resourceFile.Load("C:/phrases.xml");

   // Use the XPath utils to navigate to:
   //    Test...

   XPathNavigator navigator = m_resourceFile.CreateNavigator();
   XPathExpression expression = navigator.Compile("/locale/phrases/phrase[@name='" + name + "']");
   XPathNodeIterator nodeIter;

   string phraseText = null;

   // We're expecting a node set, witht he first item being the phrase tag
   // and the second (accessible via MoveNext) being the data.

   switch (expression.ReturnType)
      {
      case XPathResultType.NodeSet:
         nodeIter = navigator.Select(expression);
         if (nodeIter.MoveNext())
            {
            phraseText = nodeIter.Current.Value;
            }
         break;

      // Anything else - set the phrase to null.

      default:
         phraseText = null;
         break;
      }

   return phraseText;
   }