Reading Attributes
To harvest data from the attributes of a document, you have to explicitly reach out and touch them. If you want to determine that a node has attributes, use the HasAttributes property. If you want to list all the attributes but you don't know the specific names, you can use an indexed access method or an enumeration method to list them all.
The indexed method of attribute traversal is shown in the code fragment of Listing 4. It uses AttributeCount to get the size of the attribute collection and builds a simple for loop to move through it. The GetAttribute method returns the value of the attribute without moving the cursor, while the MoveToAttribute call actually positions the cursor on the attribute.
Listing 4: XmlReader Attributes by Index
int Count = reader.AttributeCount; for (int i = 0; i < Count; i++) { // get the attribute value string attrval = reader.GetAttribute(i); // ----- OR ------ // move cursor to the attribute node reader.MoveToAttribute(i); string attrval = reader.Value; }
The enumeration method uses the MoveToFirstAttribute and MoveToNextAttribute methods to travel along the attribute nodes. The example in Listing 5 navigates to the attributes of the XML document using the enumeration technique. Notice how we repositioned the cursor back on the element node using the MoveToElement method. This is not necessary, but it is handy when you want to put the cursor back on the element for special processing needs.
Listing 5: XmlTextReader Elements and Attributes Navigation Code
using System; using System.Xml; namespace XmlDemos { public class ReaderNavElemAttrs { public static void Main() { // load the PO document XmlTextReader reader = new XmlTextReader("PO.xml"); // ignore the whitespace in the document reader.WhitespaceHandling = WhitespaceHandling.None; Console.WriteLine("Walking nodes in document..\n"); // read each node in the document while (reader.Read()) { // call routine for printing out spacing PrintDepth(reader.Depth); // display node information Console.WriteLine("Name:{0} Type:{1} Value:{2}", reader.Name, reader.NodeType, reader.Value); // check to see if the current node has attributes if (reader.HasAttributes) { // move to the first attribute reader.MoveToFirstAttribute(); // enumerate all attributes while (reader.MoveToNextAttribute()) { // display attribute information PrintDepth(reader.Depth + 1); Console.WriteLine("Name:{0} Type:{1} Value:{2}", reader.Name, reader.NodeType, reader.Value); } // move back to the element node that contains // the attributes we just traversed reader.MoveToElement(); } } } public static void PrintDepth(int depth) { for (int i=0; i < depth; i++) Console.Write(" "); } } }
Listing 6: XmlTextReader Elements and Attributes Navigation Output
Walking nodes in document.. Name:xml Type:XmlDeclaration Value:version="1.0" encoding="utf-8" Name:encoding Type:Attribute Value:utf-8 Name:po:PurchaseOrder Type:Element Value: Name:xmlns:xsd Type:Attribute Value:http://www.w3.org/2001/XMLSchema Name:xmlns:xsi Type:Attribute Value:http://www.w3.org/2001/XMLSchema-instance Name:Number Type:Element Value: Name: Type:Text Value:1001 Name:Number Type:EndElement Value: Name:OrderDate Type:Element Value: Name: Type:Text Value:8/12/01 Name:OrderDate Type:EndElement Value: Name:BillToAddress Type:Element Value: Name:Street Type:Element Value: Name: Type:Text Value:101 Main Street Name:Street Type:EndElement Value: Name:City Type:Element Value: Name: Type:Text Value:Charlotte Name:City Type:EndElement Value: Name:State Type:Element Value: Name: Type:Text Value:NC Name:State Type:EndElement Value: Name:ZipCode Type:Element Value: Name: Type:Text Value:28273 Name:ZipCode Type:EndElement Value: Name:BillToAddress Type:EndElement Value: Name:ShipToAddress Type:Element Value: Name:Street Type:Element Value: Name: Type:Text Value:101 Main Street Name:Street Type:EndElement Value: Name:City Type:Element Value: Name: Type:Text Value:Charlotte Name:City Type:EndElement Value: Name:State Type:Element Value: Name: Type:Text Value:NC Name:State Type:EndElement Value: Name:ZipCode Type:Element Value: Name: Type:Text Value:28273 Name:ZipCode Type:EndElement Value: Name:ShipToAddress Type:EndElement Value: Name:LineItem Type:Element Value: Name:Description Type:Attribute Value:Wood desk for computer Name:SKU Type:Attribute Value:12345A123 Name:Price Type:Attribute Value:499.99 Name:Qty Type:Attribute Value:1 Name:po:PurchaseOrder Type:EndElement Value: