![]() |
Languages »
C / C++ Language »
General
Intermediate
Manipulate XML data with XPath and XmlDocument (C#)By Michael ChaoAn article about manipulating XML source data. |
C#, XML.NET 1.1, Win2KVS.NET2003, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||


Based on a section of easy-to-read XML source data, I'll show you how to select and locate XML nodes and navigate through them using XPathNavigator and XPathNodeIterator. I will provide a few straightforward samples about XPath expression with which you could follow without difficulty. In the last part, there is some sample code to update, insert and remove XML nodes.
To keep this article simple and clear, I'll break it down into two parts, and put XSL, XSLT to my next article.
Here is the source XML data:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd country="USA">
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd country="UK">
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>10.0</price>
</cd>
<cd country="USA">
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<price>9.90</price>
</cd>
</catalog>
If you want to select all of the price elements, here is the code:
using System.Xml;
using System.Xml.XPath;
....
string fileName = "data.xml";
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
// Compile a standard XPath expression
XPathExpression expr;
expr = nav.Compile("/catalog/cd/price");
XPathNodeIterator iterator = nav.Select(expr);
// Iterate on the node set
listBox1.Items.Clear();
try
{
while (iterator.MoveNext())
{
XPathNavigator nav2 = iterator.Current.Clone();
listBox1.Items.Add("price: " + nav2.Value);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
In the above code, we used "/catalog/cd/price" to select all the price elements. If you just want to select all the cd elements with price greater than 10.0, you can use "/catalog/cd[price>10.0]". Here are some more examples of XPath expressions:
/catalog |
selects the root element |
/catalog/cd |
selects all the cd elements of the catalog element |
/catalog/cd/price |
selects all the price elements of all the cd elements of the catalog element |
/catalog/cd[price>10.0] |
selects all the cd elements with price greater than 10.0 |
starts with a slash(/) |
represents an absolute path to an element |
starts with two slashes(//) |
selects all elements that satisfy the criteria |
//cd |
selects all cd elements in the document |
/catalog/cd/title | /catalog/cd/artist |
selects all the title and artist elements of the cd elements of catalog |
//title | //artist |
selects all the title and artist elements in the document |
/catalog/cd/* |
selects all the child elements of all cd elements of the catalog element |
/catalog/*/price |
selects all the price elements that are grandchildren of catalog |
/*/*/price |
selects all price elements which have two ancestors |
//* |
selects all elements in the document |
/catalog/cd[1] |
selects the first cd child of catalog |
/catalog/cd[last()] |
selects the last cd child of catalog |
/catalog/cd[price] |
selects all the cd elements that have price |
/catalog/cd[price=10.90] |
selects cd elements with the price of 10.90 |
/catalog/cd[price=10.90]/price |
selects all price elements with the price of 10.90 |
//@country |
selects all "country" attributes |
//cd[@country] |
selects cd elements which have a "country" attribute |
//cd[@*] |
selects cd elements which have any attribute |
//cd[@country='UK'] |
selects cd elements with "country" attribute equal to 'UK' |
To update a cd node, first I search out which node you are updating by SelectSingleNode, and then create a new cd element. After setting the InnerXml of the new node, call ReplaceChild method of XmlElement to update the document. The code is as follows:
XmlTextReader reader = new XmlTextReader(FILE_NAME);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
reader.Close();
//Select the cd node with the matching title
XmlNode oldCd;
XmlElement root = doc.DocumentElement;
oldCd = root.SelectSingleNode("/catalog/cd[title='" + oldTitle + "']");
XmlElement newCd = doc.CreateElement("cd");
newCd.SetAttribute("country",country.Text);
newCd.InnerXml = "<title>" + this.comboBox1.Text + "</title>" +
"<artist>" + artist.Text + "</artist>" +
"<price>" + price.Text + "</price>";
root.ReplaceChild(newCd, oldCd);
//save the output to a file
doc.Save(FILE_NAME);
Similarly, use InsertAfter and RemoveChild to insert and remove a node, check it out in the demo. When you run the application, make sure that "data.xml" is in the same directory as the EXE file.
Anyway, XmlDocument is an in-memory or cached tree representation of an XML document. It is somewhat resource-intensive, if you have a large XML document and not enough memory to consume, use XmlReader and XmlWriter for better performance.
Version 1.0, it's my first article on CP, I expect there are many flaws. The XML source data and the knowledge comes from the web and MSDN, I just wrote a demo app to show them. No copyright reserved.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 4 Feb 2005 Editor: Smitha Vijayan |
Copyright 2005 by Michael Chao Everything else Copyright © CodeProject, 1999-2009 Web10 | Advertise on the Code Project |