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

 


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!

Comments

Add Comment