Master C# Logo banner
Welcome to MasterCSharp.com - Master C#, the easy way... - by Saurabh Nandu

 


Working with Xml DOM

Add Comment
 

 
<div align="center"> <table width="75%" class="outline"> <tr> <td width="50%" class="outline"><b>Download</b></td> <td width="50%" class="outline"><b>SDK</b></td> </tr> <tr> <td width="50%" class="outline"> <a class="wbox" href="../../file/xmldom.zip">xmldom.zip</a> (5kb)</td> <td width="50%" class="outline">Beta2</td> </tr> </table> </div> <p> <span class=wboxheado>Introduction</span><br> <b>Xml</b> - The standard for representing data over the internet is indeed very powerful and has a lot of importance in today's connected world, but very few platforms have been able to fully support Xml and its various specifications.<br> On the .NET Platform, Microsoft has clearly displayed its interest in supporting Xml by providing an extensive API that fully supports the latest Xml standards. </p> <p><span class=wboxheado>Xml DOM</span><br> <a class="wbox" target="_blank" href="http://www.W3C.org">W3C</a> has specified the <b>Xml DOM</b> (Document Object Model) as a standard programming interface for handling Xml Documents. The Xml DOM treats a Xml Document as a tree of nodes. Every individual data item is treated as a Node, any text or sub data items are treated as sub-nodes (child nodes).&nbsp;</p> <p><b>Table 1:</b> Possible Node Types according to W3C and corresponding .NET Class&nbsp;</p> <table border="0" width="100%" class="outline"> <tr> <td width="50%" class="outline"><b>Xml Node Type</b></td> <td width="50%" class="outline"><b>.NET Framework Class</b></td> </tr> <tr> <td width="50%" class="outline">Element</td> <td width="50%" class="outline">XmlElement</td> </tr> <tr> <td width="50%" class="outline">Attribute</td> <td width="50%" class="outline">XmlAttribute</td> </tr> <tr> <td width="50%" class="outline">Text</td> <td width="50%" class="outline">XmlText</td> </tr> <tr> <td width="50%" class="outline">CDATA Section</td> <td width="50%" class="outline">XmlCDataSection</td> </tr> <tr> <td width="50%" class="outline">Entity Reference</td> <td width="50%" class="outline">XmlEntityReference</td> </tr> <tr> <td width="50%" class="outline">Entity</td> <td width="50%" class="outline">XmlEntity</td> </tr> <tr> <td width="50%" class="outline">Processing Instruction</td> <td width="50%" class="outline">XmlProcessingInstruction</td> </tr> <tr> <td width="50%" class="outline">Comment</td> <td width="50%" class="outline">XmlComment</td> </tr> <tr> <td width="50%" class="outline">Document</td> <td width="50%" class="outline">XmlDocument</td> </tr> <tr> <td width="50%" class="outline">Document Type</td> <td width="50%" class="outline">XmlDocumentType</td> </tr> <tr> <td width="50%" class="outline">Document Fragment</td> <td width="50%" class="outline">XmlDocumentFragement</td> </tr> <tr> <td width="50%" class="outline">Notation</td> <td width="50%" class="outline">XmlNotation</td> </tr> </table> <p>The .NET Framework places these classes under the '<b>System.Xml</b>' namespace, '<b>System.dll</b>' assembly. The .NET SDK Beta2 provides full support W3C <b>Xml DOM level 1 (core)</b> 'http://www.w3c.org/TR/REC-DOM-Level-1/' as well as for W3C <b>Xml DOM level 2</b> 'http://www.w3c.org/TR/DOM-Level-2/'.</p> <p><span class=wboxheado>Code:</span><br> In this article we will learn to manipulate data within a Xml document using the Xml DOM specification. Of course please remember that the focus of this article is to help you learn C# Programming and not Xml DOM!</p> <p>1) <b>Contacts.Xml </b>: Xml Document<table border="0" width="100%" class="code"> <tr> <td width="100%"> <pre>&lt;?xml version=&quot;1.0&quot;?&gt; &lt;Contacts&gt; &lt;Contact ContactID=&quot;1021&quot;&gt; &lt;FirstName&gt;Nanu&lt;/FirstName&gt; &lt;LastName&gt;Jogi&lt;/LastName&gt; &lt;/Contact&gt; &lt;Contact ContactID=&quot;3267&quot;&gt; &lt;FirstName&gt;Saurabh&lt;/FirstName&gt; &lt;LastName&gt;Nandu&lt;/LastName&gt; &lt;/Contact&gt; &lt;Contact ContactID=&quot;1002&quot;&gt; &lt;FirstName&gt;Pritesh&lt;/FirstName&gt; &lt;LastName&gt;Nandu&lt;/LastName&gt; &lt;/Contact&gt; &lt;/Contacts&gt;</pre> </td> </tr> </table>&nbsp; <p>2) <b>Contacts.cs</b> - The Example Class</p> <table border="0" width="100%" class="code"> <tr> <td width="100%"> <pre>using System; using System.Xml; using System.IO; public class Contacts { private XmlDocument contactDoc; <span class=cmt>//Path to the data file</span> private string docPath=&quot;contacts.xml&quot;; public static void Main() { Contacts myContacts = new Contacts(); } public Contacts() { <span class=cmt>//Open a FileStream on the Xml file</span> FileStream docIn = new FileStream(docPath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite); contactDoc = new XmlDocument(); <span class=cmt>//Load the Xml Document</span> contactDoc.Load(docIn); <span class=cmt>//Display the contacts</span> DisplayContacts(); <span class=cmt>//Add a Contact</span> AddContact(); <span class=cmt>//Display the contacts</span> DisplayContacts(); <span class=cmt>//Edit a Contact</span> EditContact(); <span class=cmt>//Display the contacts</span> DisplayContacts(); <span class=cmt>//Delete a Contact</span> DeleteContact(); <span class=cmt>//Display the contacts</span> DisplayContacts(); }</pre> </td> </tr> </table> <p>Above is the definition of the class <b>Contacts</b>, this is a normal <i>Console Application</i>. Within the class I define two private variables, one is of the type <b>XmlDocument</b> and other is a string holding the path to the Xml Document.<br> Then in the constructor of the class I make calls to various methods which will manipulate the Xml data using the Xml DOM.</p> <table width="100%" class="code"> <tr> <td > <pre> private void DisplayContacts() { <span class=cmt>//Get a list of all XmlNodes with the TAG Contact</span> XmlNodeList contactsList = contactDoc.GetElementsByTagName(&quot;Contact&quot;); Console.WriteLine(&quot;Displaying the Contacts... \r\n&quot;); <span class=cmt>//Iterate through the Nodes</span> for(int i=0;i&lt;contactsList.Count;i++) { <span class=cmt>//Get the AttribuitesCollection for the Contact element</span> XmlAttributeCollection attrColl = contactsList[i].Attributes; <span class=cmt>//Display the Attribute Name and Value</span> Console.Write(&quot;Contact &quot;+attrColl[0].Name); Console.WriteLine(&quot;:\t&quot;+attrColl[0].Value); <span class=cmt>//Display the FirstChild element's Name and Text</span> Console.Write(&quot;Contact &quot;+contactsList[i].FirstChild.Name); Console.WriteLine(&quot;:\t&quot;+contactsList[i].FirstChild.InnerText); <span class=cmt>//Display the LastChild element's Name and Text</span> Console.Write(&quot;Contact &quot;+contactsList[i].LastChild.Name); Console.WriteLine(&quot;:\t&quot;+contactsList[i].LastChild.InnerText); Console.WriteLine(); } Console.WriteLine(&quot;Contacts List Over... \r\n\r\n&quot;); }</pre> </td> </tr> </table> <p>The above listing shows the implementation of the <b>DisplayContacts</b> method, this method iterates over all the XmlNode's in the document and displays their content. My implementation is very tightly coupled with the Xml data that I am going to work with, incase you need a generic method to iterate over the XmlNode's refer to the <i>Quick Start</i> tutorials.<br> <br> <img border="0" src="../../img/xmldomcon1.gif" width="332" height="263"><br> <b>Figure 1:</b> Display Contacts<br> &nbsp;</p> <table width="100%" class="code"> <tr> <td > <pre> private void AddContact() { Console.WriteLine(&quot;Adding a New Contact\r\n&quot;); <span class=cmt>//Create a new XmlElement</span> XmlElement newContact = contactDoc.CreateElement(&quot;Contact&quot;); <span class=cmt>//Create a new XmlAttribute</span> XmlAttribute idAttribute = contactDoc.CreateAttribute(&quot;ContactID&quot;); idAttribute.Value = &quot;2345&quot;; <span class=cmt>//Set the Attribute on the XmlElement</span> newContact.SetAttributeNode(idAttribute); <span class=cmt>//Create a new XmlElement</span> XmlElement firstElement = contactDoc.CreateElement(&quot;FirstName&quot;); firstElement.InnerText=&quot;Nitin&quot;; <span class=cmt>//Add the Append the element as an child</span> newContact.AppendChild(firstElement); XmlElement lastElement = contactDoc.CreateElement(&quot;LastName&quot;); lastElement.InnerText=&quot;Batta&quot;; newContact.AppendChild(lastElement); <span class=cmt>//Insert the newly created XmlElement into the XmlDocument //before the LastChild</span> contactDoc.DocumentElement.InsertBefore(newContact, contactDoc.DocumentElement.LastChild); <span class=cmt>//Create a FileStream and Save the Document</span> FileStream docOut = new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite); contactDoc.Save(docOut); }</pre> </td> </tr> </table> <p>The above <b>AddContact</b> method is used to append a new contact to the document. I have used the XmlDocment class's methods to create new <b>XmlAttribute</b>'s and <b>XmlElement</b>'s. Finally the XmlNode is inserted in the XmlDocument before the <i>LastChild</i> and the document is saved.<br> <br> <img border="0" src="../../img/xmldomcon2.gif" width="332" height="323"><br> <b>Figure 2:</b> Add a new Contact</p> <table width="100%" class="code"> <tr> <td > <pre> private void EditContact() { Console.WriteLine(&quot;Editing a Contact\r\n&quot;); <span class=cmt>//Use an XPath query to find a XmlNode</span> XmlNode editContact = contactDoc.SelectSingleNode(&quot;descendant::Contact[FirstName='Nitin']&quot;); <span class=cmt>//Check if the XmlNode has Child Nodes</span> if(editContact.HasChildNodes) { <span class=cmt>//Change the FirstChild Elemets InnerText</span> editContact.FirstChild.InnerText=&quot;Sanddy&quot;; } <span class=cmt>//Save the Document</span> FileStream docOut = new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite); contactDoc.Save(docOut); }</pre> </td> </tr> </table> <p>The <b>EditContact</b> method shown above executes an <b>XPath</b> query on the Xml Document and selects the XmlNode with the element <b>Contact</b> which has an <i>ChildElement FirstName</i> equal to <b>Nitin</b>. Once we have the XmlNode, we change the text of the <i>FirstName</i> element and save the file.<br> <br> <img border="0" src="../../img/xmldomcon3.gif" width="332" height="323"><br> <b>Figure 3:</b> Edit a Contact</p> <table width="100%" class="code"> <tr> <td > <pre> private void DeleteContact() { Console.WriteLine(&quot;Deleting a Contact\r\n&quot;); <span class=cmt>//Use an XPath query to find a XmlNode</span> XmlNode deleteContact = contactDoc.SelectSingleNode(&quot;descendant::Contact[FirstName='Sanddy']&quot;); <span class=cmt>//Remove the XmlNode from the Document</span> contactDoc.DocumentElement.RemoveChild(deleteContact); <span class=cmt>//Save the Document</span> FileStream docOut = new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite); contactDoc.Save(docOut); }</pre> </td> </tr> </table> <p>Just like the <b>EditContact</b> method, in the <b>DeleteContact</b> method too we use an <b>XPath </b>query to select the XmlNode having the <i>FirstName</i> child element's value equal to <b>Sanddy</b>. Once the Node is found we remove it from the document and save the document.</p> <p><span class=wboxheado>Conclusion</span><br> In this article we saw how to manipulate Xml data using the Xml DOM classes from the .NET Framework. You can modify these methods and dig a bit more into the reference documentation to get more information!</p>

Comments

Add Comment