Introduction
Ok, you all heard about XML, which allows you to package your data or other
information in a platform independent (and easy-to-use) way. It is no big
deal, everyone can invent his/her own method to do this. The real big
deal is that a lot of people have already accepted the XML concept and there
are some good tools to store, manipulate, and transport data in XML format.
The .NET Framework includes a class XmlDocument in the name
space System.Xml that is really easy to use. An XmlDocument
object consists a set of XmlNode objects and each of these nodes may
contain other nodes. The XmlDocument
class is derived from the XmlNode
class and hence a document object is also a node. So, an XmlDocument object is simply a tree structure.
I wrote a class XMLDocumentEx based
on XmlDocument that helps
you manipulate data stored in XML documents. This class has the following
methods:
public bool AddNode(XmlNode oSource, String sName);
public bool AddNode(XmlNode oSource, String sName, String sParent);
public bool AddNodes(XmlNodeList oSourceList, String sName);
public bool AddNodes(XmlNodeList oSourceList, String sName, String sParent);
public bool MergeNode(XmlNode oSource, String sName);
public bool MergeNode(XmlNode oSource, String sName, String sParent);
// fine print: the current versions of AddNode
and MergeNode methods do not copy attributes of the source node
Examples
First, we give an example of the AddNode
method. Suppose we have two XmlDocument
objects which contain the following data:
docVechile.xml
<VehicleData>
<Record>
<id>1001</id>
<make>Ford</make>
<model>Escort</model>
<year>1984</year>
</Record>
<Record>
<id>1002</id>
<make>Toyota</make>
<model>Tercel</model>
<year>1996</year>
</Record>
<Record>
<id>1003</id>
<make>Mazda</make>
<model>GLC</model>
<year>1985</year>
</Record>
</VehicleData>
docDriver.xml
<DriverData>
<Record>
<id>1</id>
<firstname>Albert</firstname>
<lastname>Einstein</lastname>
</Record>
<Record>
<id>2</id>
<firstname>Clint</firstname>
<lastname>Eastwood</lastname>
</Record>
<Record>
<id>3</id>
<firstname>James</firstname>
<lastname>Bond</lastname>
</Record>
</DriverData>
The following code will add a vehicle record and a driver record into a newly
created XMLDocumentEx object:
Dim myDoc As XMLDocumentEx = New XMLDocumentEx()
myDoc.LoadXml("<Data></Data>")
myDoc.AddNode(docVehicle.SelectSingleNode("//Record"), "VehicleRecord", "Data")
myDoc.AddNode(docDriver.SelectSingleNode("//Record"), "DriverRecord", "Data")
myDoc.xml
<Data>
<VehicleRecord>
<id>...</id>
<make>...</make>
<model>...</model>
<year>...</year>
</ Vehicle Record>
<DriverRecord>
<id>...</id>
<firstname>...</firstname>
<lastname>...</lastname>
</DriverRecord>
</Data>
If you want to add all vehicle and driver records to a new XMLDocumentEx object, then you can use the AddNodes method as in the following code:
Dim myDoc As XMLDocumentEx = New XMLDocumentEx()
myDoc.LoadXml("<Data> <VehicleData></Vehicle Data><DriverData></DriverData> </Data>")
myDoc.AddNodes(docVehicle.SelectNodes("//Record"), "VehicleRecord", " Vehicle Data")
myDoc.AddNodes(docDriver.SelectNodes("//Record"), "DriverRecord", "DriverData")
myDoc.xml
<Data>
<VehicleData>
<VehicleRecord>
<id>1001</id>
<make>Ford</make>
<model>Escort</model>
<year>1984</year>
</VehicleRecord>
<VehicleRecord>
<id>1002</id>
<make>Toyota</make>
<model>Tercel</model>
<year>1996</year>
</VehicleRecord>
<VehicleRecord>
<id>1003</id>
<make>Mazda</make>
<model>GLC</model>
<year>1985</year>
</VehicleRecord>
</VehicleData>
<DriverData>
<DriverRecord>
<id>1</id>
<firstname>Albert</firstname>
<lastname>Einstein</lastname>
</DriverRecord>
<DriverRecord>
<id>2</id>
<firstname>Clint</firstname>
<lastname>Eastwood</lastname>
</DriverRecord>
<DriverRecord>
<id>3</id>
<firstname>James</firstname>
<lastname>Bond</lastname>
</DriverRecord>
</DriverData>
</Data>
Now, lets see the MergeNode method.
If we have two XmlDocument objects docBook1, docBook2,
and each of these two documents contains a <Book> node. The <Book>
node in docBook1 contains nodes <Introduction>, <Chapter1>,
and <Chapter2>. The <Book> node in docBook2
contains nodes <Chapter3>, <Chapter4>, and <Chapter5>.
The following code will merge these nodes into a new XMLDocumentEx object:
Dim myDoc As XMLDocumentEx = New XMLDocumentEx()
myDoc.LoadXml("<Data> <Book></Book></Data> ")
myDoc.MergeNode(docBook1.SelectSingleNode("//Book"), "Book", "Data ")
myDoc.MergeNode(docBook2.SelectSingleNode("//Book"), "Book", "Data")
myDoc.xml
<Data>
<Book>
<Introduction>...</Introduction>
< Chapter1 >...</Chapter1>
<Chapter2>...</Chapter2>
<Chapter3>...</Chapter3>
<Chapter4>...</Chapter4>
<Chapter5>...</Chapter5>
</Book>
</Data>
The source code
Here is the complete C# source
code of the XMLDocumentEx class
with comments.
sealed public class XMLDocumentEx: XmlDocument
{
public bool AddNode(XmlNode oSource, String sName)
{
return AddNode(oSource, sName, null);
}
public bool AddNode(XmlNode oSource, String sName, String sParent)
{
try
{
if(sName!=null&&oSource!= null)
{
XmlNode oNewNode = CreateElement(sName);
oNewNode.InnerXml = oSource.InnerXml;
if(sParent!= null) sParent = sParent.Trim();
if(sParent== null||sParent.Equals(String.Empty))
{
DocumentElement.AppendChild(oNewNode);
return true;
}
else
{
if (!sParent.Substring(0,2).Equals("//")) sParent = "//"+sParent;
XmlNode oParent = SelectSingleNode(sParent);
if (oParent!=null)
{
oParent.AppendChild(oNewNode);
return true ;
}
}
}
}
catch (Exception)
{
}
return false;
}
public bool AddNodes(XmlNodeList oSourceList, String sName)
{
return AddNodes(oSourceList, sName, null);
}
public bool AddNodes(XmlNodeList oSourceList, String sName, String sParent)
{
try
{
if(oSourceList!= null)
{
int i = 0;
while(i<oSourceList.Count)
{
if (!AddNode(oSourceList.Item(i),sName,sParent)) return false;
i++;
}
return true;
}
}
catch (Exception)
{
}
return false;
}
public bool MergeNode(XmlNode oSource, String sName)
{
return MergeNode(oSource, sName, null );
}
public bool MergeNode(XmlNode oSource, String sName, String sParent)
{
try
{
if(sName!=null&&oSource!= null)
{
XmlNode theNode = null ;
if(sParent!= null) sParent = sParent.Trim();
if(sParent== null||sParent.Equals(String.Empty))
{
theNode = SelectSingleNode("//"+sName);
if (theNode==null)
{
theNode = CreateElement(sName);
DocumentElement.AppendChild(theNode);
}
}
else
{
if (!sParent.Substring(0,2).Equals("//")) sParent = "//"+sParent;
XmlNode theParent = SelectSingleNode(sParent);
if (theParent!=null)
{
theNode = theParent.SelectSingleNode(sName);
if(theNode==null)
{
theNode = CreateElement(sName);
theParent.AppendChild(theNode);
}
}
}
if(theNode!= null)
{
theNode.InnerXml += oSource.InnerXml;
return true;
}
}
}
catch (Exception)
{
}
return false;
}
}
Thanks for reading. Check out my home page for
other articles and tools .