Chapter 5: XML Processing


One of the most remarkable aspects of the Microsoft .NET Framework is its deep integration with XML. In many .NET applications, you won't even be aware that you're using XML technologies ”they'll just be used behind the scenes when you serialize a Microsoft ADO.NET DataSet , call an XML Web service, or read application settings in a Web.config configuration file. In other cases, you'll want to work directly with the System.Xml namespaces to manipulate XML data. Common XML tasks don't just include parsing an XML file, but also validating it against a schema, applying an XSL transform to create a new document or HTML page, and searching intelligently with XPath. The recipes in this chapter include the following:

  • Techniques for reading, parsing, and manipulating XML data (recipes 5.1, 5.2, 5.3, and 5.7).

  • Ways to search an XML document for specific nodes, either by name (recipe 5.4), by namespace (recipe 5.5), or using XPath (recipe 5.6).

  • How to validate an XML document with an XML schema (recipe 5.8).

  • Approaches for serializing an object to XML (recipe 5.9), creating an XML schema for a class (recipe 5.10), and generating the source code for a class based on an XML schema (recipe 5.11).

  • How to transform an XML document to another document using an XSLT stylesheet (recipe 5.12).

5.1 Show the Structure of an XML Document in a TreeView

Problem

You need to display the structure and content of an XML document in a Windows-based application.

Solution

Load the XML document using the System.Xml.XmlDocument class. Create a re- entrant method that converts a single XmlNode into a System.Windows.Forms.TreeNode , and call it recursively to walk through the entire document.

Discussion

The .NET Framework provides several different ways to process XML documents. The one you use depends in part upon your programming task. One of the most fully featured classes is XmlDocument , which provides an in-memory representation of an XML document that conforms to the W3C Document Object Model (DOM). The XmlDocument class allows you to browse through the nodes in any direction, insert and remove nodes, and change the structure on the fly. For details of the DOM specification, go to http://www.w3c.org .

To use the XmlDocument class, simply create a new instance of the class, and call the Load method with a filename, a Stream , a TextReader , or an XmlReader object. You can even supply a URL that points to an XML document. The XmlDocument instance will be populated with the tree of elements, or nodes, from the source document. The entry point for accessing these nodes is the root element, which is provided through the XmlDocument.DocumentElement property. DocumentElement is an XmlElement object that can contain one or more nested XmlNode objects, which in turn can contain more XmlNode objects, and so on. An XmlNode is the basic ingredient of an XML file. Common XML nodes include elements, attributes, comments, and contained text.

When dealing with an XmlNode or a class that derives from it (such as XmlElement or XmlAttribute ), you can use the following basic properties:

  • ChildNodes is an XmlNodeList collection that contains the first level of nested nodes.

  • Name is the name of the node.

  • NodeType returns a member of the System.Xml.XmlNodeType enumeration that indicates the type of the node (element, attribute, text, and so on).

  • Value is the content of the node, if it's a text or CDATA node.

  • Attributes provides a collection of node objects representing the attributes applied to the element.

  • InnerText retrieves a string with the concatenated value of the node and all nested nodes.

  • InnerXml retrieves a string with the concatenated XML markup for all nested nodes.

  • OuterXml retrieves a string with the concatenated XML markup for the current node and all nested nodes.

The following example walks through every element of an XmlDocument using the ChildNodes property and a recursive method. Each node is displayed in a TreeView control, with descriptive text that either identifies it or shows its content.

 using System; using System.Windows.Forms; using System.Xml; public class XmlTreeDisplay : System.Windows.Forms.Form{     private System.Windows.Forms.Button cmdLoad;     private System.Windows.Forms.Label lblFile;     private System.Windows.Forms.TextBox txtXmlFile;     private System.Windows.Forms.TreeView treeXml;     // (Designer code omitted.)     private void cmdLoad_Click(object sender, System.EventArgs e) {              // Clear the tree.         treeXml.Nodes.Clear();         // Load the XML Document         XmlDocument doc = new XmlDocument();         try {             doc.Load(txtXmlFile.Text);         }catch (Exception err) {             MessageBox.Show(err.Message);             return;         }         // Populate the TreeView.         ConvertXmlNodeToTreeNode(doc, treeXml.Nodes);         // Expand all nodes.         treeXml.Nodes[0].ExpandAll();     }     private void ConvertXmlNodeToTreeNode(XmlNode xmlNode,        TreeNodeCollection treeNodes) {         // Add a TreeNode node that represents this XmlNode.         TreeNode newTreeNode = treeNodes.Add(xmlNode.Name);         // Customize the TreeNode text based on the XmlNode         // type and content.         switch (xmlNode.NodeType) {                      case XmlNodeType.ProcessingInstruction:             case XmlNodeType.XmlDeclaration:                 newTreeNode.Text = "<?" + xmlNode.Name + " " +                    xmlNode.Value + "?>";                 break;             case XmlNodeType.Element:                 newTreeNode.Text = "<" + xmlNode.Name + ">";                 break;             case XmlNodeType.Attribute:                 newTreeNode.Text = "ATTRIBUTE: " + xmlNode.Name;                 break;             case XmlNodeType.Text:             case XmlNodeType.CDATA:                 newTreeNode.Text = xmlNode.Value;                 break;             case XmlNodeType.Comment:                 newTreeNode.Text = "<!--" + xmlNode.Value + "-->";                 break;         }         // Call this routine recursively for each attribute.         // (XmlAttribute is a subclass of XmlNode.)         if (xmlNode.Attributes != null) {             foreach (XmlAttribute attribute in xmlNode.Attributes) {                 ConvertXmlNodeToTreeNode(attribute, newTreeNode.Nodes);             }         }         // Call this routine recursively for each child node.         // Typically, this child node represents a nested element,         // or element content.         foreach (XmlNode childNode in xmlNode.ChildNodes) {             ConvertXmlNodeToTreeNode(childNode, newTreeNode.Nodes);         }     } } 

As an example, consider the following simple XML file (which is included with the sample code as the ProductCatalog.xml file):

 <?xml version="1.0" ?> <productCatalog>     <catalogName>Jones and Jones Unique Catalog 2004</catalogName>     <expiryDate>2005-01-01</expiryDate>     <products>         <product id="1001">             <productName>Gourmet Coffee</productName>             <description>The finest beans from rare Chilean              plantations.</description>             <productPrice>0.99</productPrice>             <inStock>true</inStock>         </product>         <product id="1002">             <productName>Blue China Tea Pot</productName>             <description>A trendy update for tea drinkers.</description>             <productPrice>102.99</productPrice>             <inStock>true</inStock>         </product>     </products> </productCatalog> 

Figure 5.1 shows how this file will be rendered in the XmlTreeDisplay form.


Figure 5.1: The displayed structure of an XML document.



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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