- The Common Node
- Navigating the DOM
- Key Extended Nodes
- Building the DOM
- Conclusion
Building the DOM
Building XML documents results from a factory approach with a well-known object that is responsible for creating requests. XmlDocument plays the role of builder through a set of Create methods that are capable of constructing any type of node in the XML document, as listed here:
CreateAttribute
CreateCDataSection
CreateComment
CreateDocumentFragment
CreateDocumentType
CreateElement
CreateEntityReference
CreateNode
CreateProcessInstruction
CreateSignificantWhitespace
CreateTextNode
CreateWhitespace
CreateXmlDeclaration
ImportNode
After you have created the appropriate type of node with XmlDocument, you need to graft it onto the tree at the right location. This next list shows the node-management functions for element nodes.
AppendChild
Clone
CloneNode
InsertAfter
InsertBefore
PrependChild
ReplaceChild
RemoveChild
Normalize
The following list shows how to manage attribute nodes in the Attributes property on each node.
Append
CopyTo
InsertAfter
InsertBefore
Prepend
Remove
RemoveAll
RemoveAt
GetNamedItem
SetNamedItem
RemoveNamedItem
Nodes have an additional building capability via the Clone and CloneNode methods. Clone and CloneNode called with a true Boolean parameter will build a deep copy of all attributes and subelements and content below the node being cloned. CloneNode called with a false Boolean parameter is the only way to conduct a shallow copy. The XmlDocument has an additional capability to copy in nodes from an external document or fragment using the ImportNode method.
The example is Listing 6 uses the DOM creation facilities to build a new purchase order document. The BuildPO method drives the creation process and builds simple element-content nodes by creating text nodes and containing element nodes. BuildPO delegates construction of complex content to the BuildAddress and BuildLineItem methods. The BuildLineItem method is unique because it has to access the Attributes collection of its single element node to add the attributes that represent the properties of the line item. The resulting document is shown in Listing 7.
Listing 6: Code to Produce PO XML Document Programmatically
using System; using System.Xml; namespace XmlDOM { class DOMCreateTutorial { static void Main(string[] args) { // Build a new version of the PO programmatically Console.WriteLine("Building PO..."); XmlDocument newdom = BuildPO(); newdom.Save("C:\\NewPO.xml"); } static XmlDocument BuildPO() { XmlDocument dom = new XmlDocument(); XmlNode text; XmlElement elem; XmlElement docelem; // Document element docelem = dom.CreateElement("PurchaseOrder"); dom.AppendChild(docelem); // Number elem = dom.CreateElement("Number"); text = dom.CreateTextNode("1002"); elem.AppendChild(text); docelem.AppendChild(elem); // OrderDate elem = dom.CreateElement("OrderDate"); text = dom.CreateTextNode("8/13/01"); elem.AppendChild(text); docelem.AppendChild(elem); // BillToAddress elem = BuildAddress(dom, "BillToAddress", "101 Main Street", "Charlotte", "NC", "28273"); docelem.AppendChild(elem); // ShipToAddress elem = BuildAddress(dom, "ShipToAddress", "101 Main Street", "Charlotte", "NC", "28273"); docelem.AppendChild(elem); // LineItem elem = BuildLineItem(dom, "Computer Desk", "Wood desk for computer", "12345A123", 499.99M, 1); docelem.AppendChild(elem); // Clone the Line Item (deep clone) XmlNode clonenode = elem.CloneNode(true); clonenode.Attributes["Description"].Value = "Metal desk for computer"; clonenode.Attributes["SKU"].Value = "12345B345"; clonenode.Attributes["Price"].Value = "1099.99"; docelem.AppendChild(clonenode); return dom; } static XmlElement BuildAddress(XmlDocument dom, string name, string street, string city, string state, string zipcode) { XmlElement elem; XmlElement subelem; XmlNode text; // name of address elem = dom.CreateElement(name); // Street subelem = dom.CreateElement("Street"); text = dom.CreateTextNode(street); subelem.AppendChild(text); elem.AppendChild(subelem); // City subelem = dom.CreateElement("City"); text = dom.CreateTextNode(city); subelem.AppendChild(text); elem.AppendChild(subelem); // State subelem = dom.CreateElement("State"); text = dom.CreateTextNode(state); subelem.AppendChild(text); elem.AppendChild(subelem); // ZipCode subelem = dom.CreateElement("ZipCode"); text = dom.CreateTextNode(zipcode); subelem.AppendChild(text); elem.AppendChild(subelem); return elem; } static XmlElement BuildLineItem(XmlDocument dom, string name, string description, string SKU, decimal price, int quantity) { XmlElement elem; XmlAttribute subattr; elem = dom.CreateElement("LineItem"); // Name subattr = dom.CreateAttribute("Name"); subattr.Value = name; elem.Attributes.Append(subattr); // Description subattr = dom.CreateAttribute("Description"); subattr.Value = description; elem.Attributes.Append(subattr); // SKU subattr = dom.CreateAttribute("SKU"); subattr.Value = SKU; elem.Attributes.Append(subattr); // Price subattr = dom.CreateAttribute("Price"); subattr.Value = price.ToString(); elem.Attributes.Append(subattr); // Qty subattr = dom.CreateAttribute("Qty"); subattr.Value = quantity.ToString(); elem.Attributes.Append(subattr); return elem; } } }
Listing 7: NewPO.Xml Document
<PurchaseOrder> <Number>1002</Number> <OrderDate>8/13/01</OrderDate> <BillToAddress> <Street>101 Main Street</Street> <City>Charlotte</City> <State>NC</State> <ZipCode>28273</ZipCode> </BillToAddress> <ShipToAddress> <Street>101 Main Street</Street> <City>Charlotte</City> <State>NC</State> <ZipCode>28273</ZipCode> </ShipToAddress> <LineItem Name="Computer Desk" Description="Wood desk for [ccc] computer" SKU="12345A123" Price="499.99" Qty="1" /> <LineItem Name="Computer Desk" Description="Metal desk for computer" SKU="12345B345" Price="1099.99" Qty="1" /> </PurchaseOrder>