Working with Xml DOM
Add Comment| Download | SDK |
| xmldom.zip (5kb) | Beta2 |
Introduction
Xml - 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.
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.
Xml DOM
W3C
has specified the Xml DOM (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).
Table 1: Possible Node Types according to W3C and corresponding .NET Class
| Xml Node Type | .NET Framework Class |
| Element | XmlElement |
| Attribute | XmlAttribute |
| Text | XmlText |
| CDATA Section | XmlCDataSection |
| Entity Reference | XmlEntityReference |
| Entity | XmlEntity |
| Processing Instruction | XmlProcessingInstruction |
| Comment | XmlComment |
| Document | XmlDocument |
| Document Type | XmlDocumentType |
| Document Fragment | XmlDocumentFragement |
| Notation | XmlNotation |
The .NET Framework places these classes under the 'System.Xml' namespace, 'System.dll' assembly. The .NET SDK Beta2 provides full support W3C Xml DOM level 1 (core) 'http://www.w3c.org/TR/REC-DOM-Level-1/' as well as for W3C Xml DOM level 2 'http://www.w3c.org/TR/DOM-Level-2/'.
Code:
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!
1) Contacts.Xml : Xml Document
<?xml version="1.0"?>
<Contacts>
<Contact ContactID="1021">
<FirstName>Nanu</FirstName>
<LastName>Jogi</LastName>
</Contact>
<Contact ContactID="3267">
<FirstName>Saurabh</FirstName>
<LastName>Nandu</LastName>
</Contact>
<Contact ContactID="1002">
<FirstName>Pritesh</FirstName>
<LastName>Nandu</LastName>
</Contact>
</Contacts>
|
2) Contacts.cs - The Example Class
using System;
using System.Xml;
using System.IO;
public class Contacts
{
private XmlDocument contactDoc;
//Path to the data file
private string docPath="contacts.xml";
public static void Main()
{
Contacts myContacts = new Contacts();
}
public Contacts()
{
//Open a FileStream on the Xml file
FileStream docIn =
new FileStream(docPath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
contactDoc = new XmlDocument();
//Load the Xml Document
contactDoc.Load(docIn);
//Display the contacts
DisplayContacts();
//Add a Contact
AddContact();
//Display the contacts
DisplayContacts();
//Edit a Contact
EditContact();
//Display the contacts
DisplayContacts();
//Delete a Contact
DeleteContact();
//Display the contacts
DisplayContacts();
}
|
Above is the definition of the class Contacts, this is a normal
Console Application. Within the class I define two private variables,
one is of the type XmlDocument and other is a string holding the path
to the Xml Document.
Then in the constructor of the class I make calls to various methods
which will manipulate the Xml data using the Xml DOM.
private void DisplayContacts()
{
//Get a list of all XmlNodes with the TAG Contact
XmlNodeList contactsList = contactDoc.GetElementsByTagName("Contact");
Console.WriteLine("Displaying the Contacts... \r\n");
//Iterate through the Nodes
for(int i=0;i<contactsList.Count;i++)
{
//Get the AttribuitesCollection for the Contact element
XmlAttributeCollection attrColl = contactsList[i].Attributes;
//Display the Attribute Name and Value
Console.Write("Contact "+attrColl[0].Name);
Console.WriteLine(":\t"+attrColl[0].Value);
//Display the FirstChild element's Name and Text
Console.Write("Contact "+contactsList[i].FirstChild.Name);
Console.WriteLine(":\t"+contactsList[i].FirstChild.InnerText);
//Display the LastChild element's Name and Text
Console.Write("Contact "+contactsList[i].LastChild.Name);
Console.WriteLine(":\t"+contactsList[i].LastChild.InnerText);
Console.WriteLine();
}
Console.WriteLine("Contacts List Over... \r\n\r\n");
}
|
The above listing shows the implementation of the DisplayContacts
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 Quick Start
tutorials.

Figure 1: Display Contacts
private void AddContact()
{
Console.WriteLine("Adding a New Contact\r\n");
//Create a new XmlElement
XmlElement newContact = contactDoc.CreateElement("Contact");
//Create a new XmlAttribute
XmlAttribute idAttribute = contactDoc.CreateAttribute("ContactID");
idAttribute.Value = "2345";
//Set the Attribute on the XmlElement
newContact.SetAttributeNode(idAttribute);
//Create a new XmlElement
XmlElement firstElement = contactDoc.CreateElement("FirstName");
firstElement.InnerText="Nitin";
//Add the Append the element as an child
newContact.AppendChild(firstElement);
XmlElement lastElement = contactDoc.CreateElement("LastName");
lastElement.InnerText="Batta";
newContact.AppendChild(lastElement);
//Insert the newly created XmlElement into the XmlDocument
//before the LastChild
contactDoc.DocumentElement.InsertBefore(newContact,
contactDoc.DocumentElement.LastChild);
//Create a FileStream and Save the Document
FileStream docOut =
new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite);
contactDoc.Save(docOut);
}
|
The above AddContact method is used to append a new contact to the
document. I have used the XmlDocment class's methods to create new
XmlAttribute's and XmlElement's. Finally the XmlNode is inserted in
the XmlDocument before the LastChild and the document is saved.

Figure 2: Add a new Contact
private void EditContact()
{
Console.WriteLine("Editing a Contact\r\n");
//Use an XPath query to find a XmlNode
XmlNode editContact =
contactDoc.SelectSingleNode("descendant::Contact[FirstName='Nitin']");
//Check if the XmlNode has Child Nodes
if(editContact.HasChildNodes)
{
//Change the FirstChild Elemets InnerText
editContact.FirstChild.InnerText="Sanddy";
}
//Save the Document
FileStream docOut =
new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite);
contactDoc.Save(docOut);
}
|
The EditContact method shown above executes an XPath query on the
Xml Document and selects the XmlNode with the element Contact which
has an ChildElement FirstName equal to Nitin. Once we have the XmlNode,
we change the text of the FirstName element and save the file.

Figure 3: Edit a Contact
private void DeleteContact()
{
Console.WriteLine("Deleting a Contact\r\n");
//Use an XPath query to find a XmlNode
XmlNode deleteContact =
contactDoc.SelectSingleNode("descendant::Contact[FirstName='Sanddy']");
//Remove the XmlNode from the Document
contactDoc.DocumentElement.RemoveChild(deleteContact);
//Save the Document
FileStream docOut =
new FileStream(docPath,FileMode.Truncate,FileAccess.Write,FileShare.ReadWrite);
contactDoc.Save(docOut);
}
|
Just like the EditContact method, in the DeleteContact method too we use an XPath query to select the XmlNode having the FirstName child element's value equal to Sanddy. Once the Node is found we remove it from the document and save the document.
Conclusion
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!

