13.2 Reading with XmlNodeReader

 <  Day Day Up  >  

13.2 Reading with XmlNodeReader

You want to parse only a given portion of an XML document by using an XmlNodeReader to process nodes from an XmlDocument object.


Technique

Unlike the XmlTextReader discussed in the previous section, the XmlNodeReader class only has a single constructor. Because the sole functionality of an XmlNodeReader is to read XML data contained within an XmlNode object, the constructor only requires a single XmlNode object as a parameter. You can create this parameter by creating an XmlDocument object, loading an XML file, and passing the XmlDocument object as the constructor parameter. This process causes the XmlNodeReader to parse the entire contents of the XML document:

 
 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load( "file.xml" ); XmlNodeReader rdr = new XmlNodeReader( xmlDoc ); 

To only parse a small fragment of the document, load the XML file using an XmlDocument object, but instead of passing the XmlDocument instance to the constructor, you can do one of two things. First, several XML objects, such as XmlAttribute , derive from the XmlNode class, which means you can pass an instance of one of these objects to the XmlDocument constructor. Second, you can use the result that is returned from calling the SelectSingleNode method defined in the XmlDocument class or any other method that returns an instance to an XmlNode object:

 
 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("books.xml"); XmlNodeReader rdr = new XmlNodeReader( xmlDoc.SelectSingleNode    ( "/bookstore/book/bk:title" )); 

Once you have an XmlNodeReader associated with an XmlNode object, you can begin reading the XML data. Reading with an XmlNodeReader is similar to the method employed in the previous section. Call the Read method and then check to see the NodeType of the data that was read. Checking the NodeType property in the XmlNodeReader instance lets you know what type of XML data was just read in, such as an element, attribute, comment, processing instruction, and so on.

Comments

The XmlNodeReader and XmlTextReader classes are strikingly similar. Other than the obvious difference that one works with XmlNode objects and the other with XML files or strings, XmlTextReader is the only reader capable of decoding Base-64 and bin-hex strings within an XML document. Therefore, if you know that your XML file will contain any of these encodings, you have to use an XmlTextReader to do so.

One other key difference, and one you'll probably see more frequently than the previous difference, is entity resolution. Each class contains a method named ResolveEntity . However, calling that method with an XmlTextReader object throws an InvalidOperationException because the XmlTextReader class, by design, does not allow entity resolution. The XmlNodeReader is capable of resolving the entities. If you are unfamiliar with entities, the best way to think of them are as string-substitution constructs within an XML file. Entity declarations are created at the beginning of the XML file and utilize a key value pairing scheme. Within the body of the XML document, preface the key name with an ampersand ( & ), which tells the XML parser to replace the key with its associated value when the ResolveEntity method is called. For example, given the following XML document, use this code:

 
 <?xml version="1.0"?> <!-- A fragment of a book store inventory database --> <!DOCTYPE book [<!ENTITY hc 'hardcover'>                               <!ENTITY sc 'softcover'>]> <bookstore xmlns:bk="urn:sampls">     <book genre="novel" publicationdate="1997" bk:ISBN="1-861001-57-8">         <bk:title>Pride And Prejudice</bk:title>         <author>          <first-name>Jane</first-name>          <last-name>Austen</last-name>         </author>         <binding>&sc;</binding>         <price>24.95</price>     </book>     <book genre="novel" publicationdate="1992" bk:ISBN="1-861002-30-1">         <bk:title>The Handmaid's Tale</bk:title>         <author>             <first-name>Margaret</first-name>             <last-name>Atwood</last-name>         </author>         <binding>&hc;</binding>         <price>29.95</price>     </book> </bookstore> 

The following code resolves any entity references and displays the result of the resolution in the output window:

 
 private void btnResolve_Click(object sender, System.EventArgs e) {     XmlNodeReader reader = null;     try     {         //Create and load an XML document.         XmlDocument doc = new XmlDocument();         doc.LoadXml( tbXML.Text );         //Create the reader.         reader = new XmlNodeReader(doc);         tbXML.Clear();         while( reader.Read() )         {             switch (reader.NodeType)             {                 case XmlNodeType.EntityReference:                 {                     tbXML.Text += "Entity " + reader.Name + " resolved to ";                     reader.ResolveEntity();                     reader.Read();                     tbXML.Text += reader.Value + "\r\n";                     break;                 }             }         }     }     finally     {         if (reader != null)             reader.Close();     } } 

When choosing between an XmlTextReader and XmlNodeReader , you have to look at the differences and similarities between the two and find the best match based on your current application design. Because of the flexibility of the two different classes, you are even able to combine the two as you see fit. For instance, if you want to use an XmlNodeReader but still want to decode bin-hex or base-64 data, simply create an XmlTextReader object and pass it the short XML fragment to decode while still leaving the majority of the processing up to the XmlNodeReader object.

 <  Day Day Up  >  


Microsoft Visual C# .Net 2003
Microsoft Visual C *. NET 2003 development skills Daquan
ISBN: 7508427505
EAN: 2147483647
Year: 2003
Pages: 440

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net