Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > PHP/MySQL/Scripting

  • Print
  • + Share This

Movement and Advanced Reads

The XmlReader API provides other advanced movement techniques that make life simpler for you and allow you to skip processing of portions of the document. This is a big win over the SAX model, which requires you to process each element. If you have left in whitespace and you want to skip certain parts of the document, you can use the MoveToContent method. It seeks nonwhitespace text, CDATA, and Element, EndElement, EntityReference, or EndEntity nodes. If the current node is not of that type, it moves the cursor until it finds one. Be careful to move the node off a content node before you call this method, or nothing happens. If you want to skip a single node, you can call the Skip method. The following shows the full list of movement functions:

  • Skip
  • MoveToContent
  • MoveToAttribute
  • MoveToElement
  • MoveToFirstAttribute
  • MoveToNextAttribute

There are also Read methods that allow more granularity and type safety when reading the document. If they are positioned on an attribute node, you can retrieve the text value of the attribute using the ReadAttributeValue call. If they are positioned on an element with text content, you can read each portion of the element with granular calls: ReadStartElement, ReadString, and ReadElement. If you are interested in just reading the text part of an element node, you can call the handy ReadElementString method. ReadInnerXml and ReadOuterXml are useful when you want to retrieve the serialized textual form of the nodes without having to parse down into them. The various Read methods are enumerated here:

  • Read
  • ReadAttributeValue
  • ReadElementStrint
  • ReadStartElement
  • ReadEndElement
  • ReadString
  • ReadChars
  • ReadInnerXML
  • ReadOuterXML

Listing 7 is a demonstration of the different ways of moving and reading the purchase order XML document. The overall loop is dependent on the EOF condition, and the cursor is moved by the combination of a MoveToContent and consumption of the content nodes that it moves to. The main logic of the code uses a chained if/then statement to check for the element nodes that you are interested in processing. The code that works on the City element shows how to process an element node with textual content by reading in the start element node, text node, and end element node. The State element-handling code shows how easy it is to retrieve the text node value with minimal work. The code associated with the LineItem element shows how to retrieve attribute values using GetAttribute and the name of the attribute. If you reach the bottom of the if/then statement, you must execute a Read to move the cursor beyond the current content node and prevent MoveToContent from going into an infinite loop. Output is shown in Listing 8.

Listing 7: XmlTextReader Advanced Read and Movement Demo Code

using System;
using System.Xml;

namespace XmlDemo
{

public class ReaderNavMove
{

public static void Main()
{
   // load the PO document 
   XmlTextReader reader = new XmlTextReader("PO.xml");

   // leave in whitespace

   Console.WriteLine("Walking nodes in document..\n");

   // use EOF property as loop breaking mechanism
   while (!(reader.EOF))
   {
     // move the node to a content node if the 
     // current node is not one of the following:
     //non-whitespace text
     //CDATA
     //Element
     //EndElement
     //EntityReference
     //EndEntity
     reader.MoveToContent();

     Console.WriteLine("Node Type:{0} Name: {0}", reader.NodeType,
        reader.Name);


     // check for the start of the State element
     if (reader.IsStartElement() && reader.Name.Equals("City"))
     {
        // read <City>
        reader.ReadStartElement();
        // read city name string
        Console.WriteLine(" -----> City: {0}", 
          reader.ReadString());

        // read </City>
        reader.ReadEndElement();
     }
     // check for the start of the City element
     else if (reader.IsStartElement() &&
        reader.Name.Equals("State"))
     {

        // read the state name string 
        // part between <State> ... </State>
        // ...this is much easier than the city handling
        Console.WriteLine(" -----> State: {0}",        
        reader.ReadElementString());
     }
     // check for the start of the LineItem element
     else if (reader.IsStartElement() && 
        reader.Name.Equals("LineItem"))
     {
        // read the Name attribute value 
        Console.WriteLine(" -----> LineItem Name: {0}", 
        reader.GetAttribute("Name"));
        // read the Price attribute value 
        Console.WriteLine(" -----> LineItem Price: {0}", 
        reader.GetAttribute("Price"));

        // move beyond the current element node
        reader.Read();
     }
     else
        // move to the next node
        // (this is required because the MoveToContent
        // will not move the cursor if we are currently
        // positioned on a node with content)
        reader.Read();

     }


   }

}
}

Listing 8: XmlTextReader Advanced Read and Movement Demo Output

Node Type:Element Name: Element
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
 -----> City: Charlotte
Node Type:Element Name: Element
 -----> State: NC
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
 -----> City: Charlotte
Node Type:Element Name: Element
 -----> State: NC
Node Type:Element Name: Element
Node Type:Text Name: Text
Node Type:EndElement Name: EndElement
Node Type:EndElement Name: EndElement
Node Type:Element Name: Element
 -----> LineItem Name: Computer Desk
 -----> LineItem Price: 499.99
Node Type:EndElement Name: EndElement
  • + Share This
  • 🔖 Save To Your Account

Related Resources

There are currently no related titles. Please check back later.