Using the XmlReader Classes

Using the XmlReader Classes

Classes for reading XML documents encapsulate functionalities used by applications for connecting to and reading data from XML documents. The functionalities work very similarly to those that retrieve data from a database (the database server returns a pointer of the cursor's object, which contains all requested data and allows access to this data). Clients of XML readers take a pointer to the reader's instance that is independent from the structure of the data stream that should be processed. The reader encapsulates the processed stream as an XML tree. Methods of the reader's classes enable you to move through nodes of XML (instead of moving from byte to byte, as it implemented in the simple streams). From the XML reader's point of view, the XML document is not just a simple text file. Rather, the XML document is a serialized set of nodes that are structured as a tree view. XML readers allow us to traverse forward only; we could not move to the parent node or neighbor node of the current node.

What Is an XmlReader?

The XmlReader is an abstract class that is used for building concrete functionality for reading XML. The .NET Framework contains three XML reader classes: XmlTextReader, XmlValidatingReader, and XmlNodeReader. Each class has a common set of properties and methods that are derived from the XmlReader class.


Notice that the value returned by a property sometimes depends on the class in which the property is declared. For example, the CanResolveEntity property makes sense only in the XmlValidatingReader class and returns true. In other classes, the property returns false and is not used in the application.

Using the XmlTextReader

The XmlTextReader class allows quick read-only and forward-only access to XML data streams. It checks the reasonableness of an XML document and generates exceptions in order of the mistakes it finds. This class also checks whether there are described links on the DTD in the XML. But XmlTextReader doesn't check the accordance of XML to DTD.

This class has been populated for quick processing of tolerant XML documents that are available in files, by URLs, or in streams. If you need to check an XML document's accordance to the DTD, you should use the XmlValidatingReader class.

You could create an instance of XmlTextReader class by using one of its constructors. All of them require a data sourcea stream, file, and so on. The default XmlTextReader class's constructor is marked as protected, so you are not allowed to use it directly.

Listing 8.3 illustrates a simple example of using the XmlTextReader class. This example reads the XML file and outputs to the console all the names of nodes of this one and the count attributes in each node. The example is based on the XML shown in Listing 8.4. The results of the example's processing are shown in the Listing 8.5.

Listing 8.3. XmlTextReader Source Code Sample
 using System; using System.Xml; namespace XmlTextReaderSample {   class XmlTextReaderSample   {     [STAThread]     static void Main(string[] args)     {       XmlTextReader xmlTextReader = new XmlTextReader("sample.xml");       Console.Out.WriteLine("Set of element in the 'sample.xml' document:");       while (xmlTextReader.Read())       {         if (xmlTextReader.NodeType == XmlNodeType.Element)         {           Console.Out.WriteLine((new String(' ', xmlTextReader.Depth * 3)) + "Name: <" +             xmlTextReader.Name +  ">; Depth: " + xmlTextReader.Depth.ToString() +             "; Attributes count: " + xmlTextReader.AttributeCount.ToString() + ";");         }       }     }   } } 

Listing 8.4. XML Document Processed in Listing 8.3
 <?xml version="1.0" encoding="utf-8" ?> <companies>         <company name="BMW">                 <cars>                         <car name="X3" year="2003"/>                         <car name="X5" year="2004"/>                 </cars>         </company>         <company name="Daewoo">                 <cars>                         <car name="Lanos" year="1999"/>                         <car name="Nubira" year="2000"/>                         <car name="Leganza" year="2000"/>                 </cars>         </company> </companies> 

Listing 8.5. Results of Processing Listing 8.3
 Set of element in the 'sample.xml' document: Name: <companies>; Depth: 0; Attributes count: 0;    Name: <company>; Depth: 1; Attributes count: 1;       Name: <cars>; Depth: 2; Attributes count: 0;          Name: <car>; Depth: 3; Attributes count: 2;          Name: <car>; Depth: 3; Attributes count: 2;    Name: <company>; Depth: 1; Attributes count: 1;       Name: <cars>; Depth: 2; Attributes count: 0;          Name: <car>; Depth: 3; Attributes count: 2;          Name: <car>; Depth: 3; Attributes count: 2;          Name: <car>; Depth: 3; Attributes count: 2; 

Using the XmlValidatingReader

The XmlValidatingReader class is inherited from the XmlReader class and enables you to verify the XML document according to the DTD, the XDR (XML-Data Reduced) schema, and the XSD schema. The DTD and XSD are official recommendations of W3C and XDR is the Microsoft implementation of the XML schema.

The XmlValidatingReader class is a wrapper class that is used for validating both whole XML documents and XML fragments and usually works in tandem with the XmlTextReader class. In such cases, the XmlTextReader class is used to traverse the XML document. In addition, it is used for validation.

Almost all custom logic of this class is implemented in the Read, Skip, and ReadTypedValue methods.

The Skip method ignores child elements of the current node of the XML document or fragment. (Notice that you could not skip an incorrect XML fragment. In such a case, an exception will be thrown.)

The ReadTypedValue method returns the value of node that is coerced to one of the Common Language Runtime's data types. If the method can find a correspondence between the XSD type and Common Language Runtime type, the value with Common Language Runtime type will be returned. Otherwise, the value in the string format will be returned.

Using the XmlNodeReader

The main purpose of the XmlNodeReader class is to traverse XML documents that are represented as a DOM model, but not as a stream of text. It works similarly to the XmlTextReader class with the following difference: XmlTextReader browses nodes of the XML stream, but XmlNodeReader browses XML DOM (it should be initialized by this XML DOM during constructor executing).

The set of methods presented in the XmlNodeReader class is the same as in XmlTextReader class. Also, you could use XmlValidatingReader in tandem with XmlNodeReader as well as with XmlTextReader.

Making Use of XmlConvert

The value of XML attributes commonly contains just a string entity. Occasionally, you will need to process this not as a string but as another type such as Date, Boolean, and so on. This value can be converted from a string to another type by using the static class XmlConvert or System.Convert. Although these classes are similar, the XmlConvert works according to the XSD specification and ignores the current regional settings presented on the local computer.

Consider the following example: An attribute has a value of 2-5-1980 and because of the current regional setting on the local machine, this value could be interpreted as February 5, 1980. In this case, if you were to use the System.Convert class, the sting will be correctly converted into a Date instance. However, if you use the XmlConvert class, an exception will be thrown because the XML specification declares the format of dates as YYYY-MM-DD. Therefore, you should transform the 2-5-1980 string into 1980-2-5. Because the XmlConvert class guarantees a correct transformation of data between Common Language Runtime and XSD types, it should be used when working with XML attributes' values.

The XmlConvert class can be used in another way. Sometimes there is a necessity to pass some characters that are not supported by XML specification into XML data stream. The XmlConvert class enables you to transfer and process XML with those characters. For this purpose, you could use the EncodeName and DecodeName methods. For example, some applications generate XML documents that contain tag names with characters that are not supported by the XML specification (for example, spaces). Such a name is not supported by XML, so you should use the EncodeName method to correct it. For example, assume that a tag has the name Some Tag. By invoking the EncodeName method, you will receive the following result: Some_0x0020_Tag.


The following characters are also equated to a space in XML specification: ASCII 0x0D (caret return), ASCII 0x0A (new line), ASCII 0x09 (tabulation).

As you can see, the space has been replaced with _0x0020_, which is the hexadecimal representation of a space. A sequence of characters with the format _0xHHHH_ is interpreted by the XmlConvert class as a special character that should be replaced after the DecodeName method's invocation. The following example shows the sequence of these methods' invocation (with results):

 XmlConvert.EncodeName("Some Tag"); //Result: Some_0x0020_Tag XmlConvert.DecodeName("Some_0x0020_Tag "); //Result: Some Tag 


Notice that the sequence of characters should have a format that exactly coincides with the _0xHHHH_ format. For example, if the tag name contains the string _0x020_, it will be ignored by the XmlConvert class.

    Visual C#. NET 2003 Unleashed
    Visual C#. NET 2003 Unleashed
    ISBN: 672326760
    EAN: N/A
    Year: 2003
    Pages: 316 © 2008-2017.
    If you may any questions please contact us: