One of the most basic tasks that you can perform with XML is manipulating the contents of an XML document. This includes traversing the list of nodes in the document, setting and querying attribute values, and manipulating the tree itself by creating and inserting new nodes. This section shows you how to read XML documents using the Document Object Model (DOM) ) modeled by the XmlDocument class in the System.Xml namespace. The DOM is recursive, meaning that each node has the same properties and methods as every other node in the document. Tables 8.1 and 8.2 provide a brief overview of many of the properties and methods of the XmlNode class before getting into the code sample. The XML node is the most basic unit of abstraction within a DOM-modeled document. Table 8.1. Commonly Used XmlNode PropertiesProperty | Method |
---|
Attributes | The attributes of the node (XmlAttributeCollection). | ChildNodes | The list of child nodes of the current node (XmlNodeList). | FirstChild | Returns the first child of the XML node (first being first in document order). | HasChildNodes | A Boolean that indicates whether the node has child nodes. | InnerText | Gets or sets the text inside the node. | InnerXml | Gets or sets the XML within the node. | LastChild | Returns the last child (document order relative) of the node. | Name | The name of the node. | NodeType | Indicates the type of the node. This can be several things, including (but not limited to): Document, DocumentFragment, Element, EndElement, Entity, Notation, Text, Whitespace, or XmlDeclaration. | OuterXml | The XML representing the current node and all its child nodes. | OwnerDocument | The document to which the current node belongs. | ParentNode | The parent node of the current node, if any. | PreviousSibling | Gets the node immediately preceding the current node in document order. | Value | Gets or sets the value of the current node. |
Table 8.2. Commonly Used XmlNode MethodsMethod | Description |
---|
AppendChild | Adds a child node to the end of the current list of child nodes | Clone | Creates a duplicate of the node | CreateNavigator | Creates an XPathNavigator for this node | InsertAfter | Inserts the given node immediately after the current node | InsertBefore | Inserts the given node immediately before the current node | PrependChild | Adds the given child node at the beginning of the child node list | RemoveAll | Removes all child nodes | RemoveChild | Removes the given child from the current node | SelectNodes | Selects a list of nodes matching the XPath expression (discussed in the following section) | SelectSingleNode | Selects a single node that matches the XPath expression |
The XmlDocument class, which deals with the entire document, is also itself an XmlNode. If you look at the documentation for the XmlDocument class, you'll see that it inherits from XmlNode. This fits with the DOM pattern in that the document is a node that can have child nodes. The methods in Table 8.3 show some of the additional methods available to the XmlDocument that aren't part of a standard node class. Table 8.3. XmlDocument Class MethodsMethod | Description |
---|
CreateAttribute | Creates an XmlAttribute with the given name | CreateCDataSection | Creates a CData section with the given data | CreateComment | Creates an XmlComment | CreateDocumentFragment | Creates a document fragment | CreateElement | Creates an XmlElement, an XmlNode with element-specific functionality | CreateNode | Creates an XmlNode | CreateTextNode | Creates an XmlText node | CreateWhitespace | Creates whitespace for insertion into the document | ImportNode | Imports a node from another document | Load | Loads the XML from the given file | LoadXml | Loads the XML from the given XML string | Save | Saves the XML document | Validate | Validates the XML document against a schema |
To show off the code for manipulating an XML document, we need a document. For the rest of this chapter, we will be working with a document called items.xml, which contains a list of items from a fictitious role-playing game and the various aspects of those items. The contents of this file are shown in Listing 8.1. Listing 8.1. Items.xml <?xml version="1.0" encoding="utf-8"?> <items> <item name="Flaming Sword of Doom" description= "This sword will vanquish all of your foes with a single swipe"> <attribute name="attack" value="10"/> <attribute name="weight" value="21" /> </item> <item name="Bag of Really Big Stuff" description="This bag can hold a lot of stuff."> <attribute name="weight" value="1" /> <attribute name="capacity" value="80" /> </item> <item name="Broach of Bug Smashing" description="This broach will kill any bug. Instantly."> <attribute name="weight" value="1" /> <attribute name="attack" value="11" /> <specials> <special name="killbug" description="This thing kills any bug instantly."/> </specials> </item> <item name="Wand of Traffic Vanquish" description= "A single wave of this wand will part the highway before you."> <attribute name="weight" value="5" /> <attribute name="attack" value="20" /> <specials> <special name="parttraffic" description="All nearby vehicles move out of your way." /> </specials> </item> </items> | Although XML allows you to freely mix freeform text with markup, for the purposes of the code in this chapter, the examples use XML documents as pure data storage. The code in Listing 8.2 shows the use of the XmlNode class and its associated properties and methods for traversing an XML document and displaying its contents to the console. Listing 8.2. XML Document Display Sample using System; using System.Xml; using System.Collections.Generic; using System.Text; namespace ReadWriteXml { class Program { static void Main(string[] args) { XmlDocument itemDoc = new XmlDocument(); itemDoc.Load(@"..\..\..\..\items.xml"); Console.WriteLine("DocumentElement has {0} children.", itemDoc.DocumentElement.ChildNodes.Count); // iterate through top-level elements foreach (XmlNode itemNode in itemDoc.DocumentElement.ChildNodes) { // because we know that the node is an element, we can do this: XmlElement itemElement = (XmlElement)itemNode; Console.WriteLine("\n[Item]: {0}\n{1}", itemElement.Attributes["name"].Value, itemElement.Attributes["description"].Value); if (itemNode.ChildNodes.Count == 0) Console.WriteLine("(No additional Information)\n"); else { foreach (XmlNode childNode in itemNode.ChildNodes) { if (childNode.Name.ToUpper() == "ATTRIBUTE") { Console.WriteLine("{0} : {1}", childNode.Attributes["name"].Value, childNode.Attributes["value"].Value); } else if (childNode.Name.ToUpper() == "SPECIALS") { foreach (XmlNode specialNode in childNode.ChildNodes) { Console.WriteLine("*{0}:{1}", specialNode.Attributes["name"].Value, specialNode.Attributes["description"].Value); } } } } } Console.ReadLine(); } } } | |