5.3 Quickly Append Nodes in an XML Document


Problem

You need to add nodes to an XML document without requiring lengthy, verbose code.

Solution

Create a helper function that accepts a tag name and content and can generate the entire element at once. Alternatively, use the XmlDocument.CloneNode method to copy branches of an XmlDocument .

Discussion

Inserting a single element into an XmlDocument requires several lines of code. There are several ways that you can shorten this code. One approach is to create a dedicated helper class with higher-level methods for adding elements and attributes. For example, you could create an AddElement method that generates a new element, inserts it, and adds any contained textthe three operations needed to insert most elements.

Here's an example of one such helper class:

 using System; using System.Xml; public class XmlHelper {     public static XmlNode AddElement(string tagName,        string textContent, XmlNode parent) {         XmlNode node = parent.OwnerDocument.CreateElement(tagName);         parent.AppendChild(node);         if (textContent != null) {             XmlNode content;             content = parent.OwnerDocument.CreateTextNode(textContent);             node.AppendChild(content);         }         return node;     }     public static XmlNode AddAttribute(string attributeName,       string textContent, XmlNode parent) {         XmlAttribute attribute;         attribute = parent.OwnerDocument.CreateAttribute(attributeName);         attribute.Value = textContent;         parent.Attributes.Append(attribute);         return attribute;     } } 

You can now condense the XML-generating code from recipe 5.2 with the simpler syntax shown here:

 public class GenerateXml {     private static void Main() {         // Create the basic document.         XmlDocument doc = new XmlDocument();         XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);         doc.AppendChild(docNode);         XmlNode products = doc.CreateElement("products");         doc.AppendChild(products);         // Add two products.         XmlNode product = XmlHelper.AddElement("product", null, products);         XmlHelper.AddAttribute("id", "1001", product);         XmlHelper.AddElement("productName", "Gourmet Coffee", product);         XmlHelper.AddElement("productPrice", "0.99", product);         product = XmlHelper.AddElement("product", null, products);         XmlHelper.AddAttribute("id", "1002", product);         XmlHelper.AddElement("productName", "Blue China Tea Pot", product);         XmlHelper.AddElement("productPrice", "102.99", product);         // Save the document (to the Console window rather than a file).         doc.Save(Console.Out);         Console.ReadLine();     } } 

Alternatively, you might want to take the helper methods such as AddAttribute and AddElement and make them instance methods in a custom class you derive from XmlDocument .

Another approach to simplifying writing XML is to duplicate nodes using the XmlNode.CloneNode method. CloneNode accepts a Boolean deep parameter. If you supply true , CloneNode will duplicate the entire branch, with all nested nodes.

Here's an example that creates a new product node by copying the first node.

 // (Add first product node.) // Create a new element based on an existing product. product = product.CloneNode(true); // Modify the node data. product.Attributes[0].Value = "1002"; product.ChildNodes[0].ChildNodes[0].Value = "Blue China Tea Pot"; product.ChildNodes[1].ChildNodes[0].Value = "102.99"; // Add the new element. products.AppendChild(product); 

Notice that in this case, certain assumptions are being made about the existing nodes (for example, that the first child in the item node is always the name, and the second child is always the price). If this assumption isn't guaranteed to be true, you might need to examine the node name programmatically.




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