Click here to Skip to main content
11,487,793 members (75,536 online)
Click here to Skip to main content

Manipulate XML data with XPath and XmlDocument (C#)

, 4 Feb 2005 CPOL 878.1K 10.5K 265
Rate this:
Please Sign up or sign in to vote.
An article about manipulating XML source data.

Sample Image

Introduction

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.

Some Concepts

  • XML - Extensible Markup Language, describe data structures in text format and with your own vocabularies, which means it does not use predefined tags and the meaning of these tags are not well understood.
  • XSL - Extensible Stylesheet Language, is designed for expressing stylesheets for XML documents. XSL is to XML as CSS is to HTML.
  • XML Transformation - is a user-defined algorithm that transforms a given XML document to another format, such as XML, HTML, XHTML. The algorithm is described by XSL.
  • XSLT - is designed for use as part of XSL, transforming an XML document into another XML document, or another type of document that is recognized by a browser, like HTML or XHTML. XSLT uses XPath.
  • XPath - is a set of syntax rules for defining parts of an XML document.

To keep this article simple and clear, I'll break it down into two parts, and put XSL, XSLT to my next article.

Using the code

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.

Points of Interest

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.

History

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.

Reference

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael Chao

Canada Canada
No Biography provided

Comments and Discussions

 
General5 * Pin
Thava Rajan4-Nov-14 1:40
memberThava Rajan4-Nov-14 1:40 
Questionhow to get the subchild attribute value of a tag if all childs have same tag name Pin
Member 111223268-Oct-14 3:35
memberMember 111223268-Oct-14 3:35 
QuestionMy vote of 4 Pin
Alireza_136219-Aug-13 0:05
memberAlireza_136219-Aug-13 0:05 
GeneralMy vote of 5 Pin
Member 806697717-Apr-13 10:26
memberMember 806697717-Apr-13 10:26 
QuestionWord document XML Pin
Member 984829019-Feb-13 15:27
memberMember 984829019-Feb-13 15:27 
Questionhaving some issue for if root as <catalog xmlns="xyzvalue"> [modified] Pin
hemantrautela29-Jan-13 23:53
memberhemantrautela29-Jan-13 23:53 
QuestionLike to access the XML of this format Pin
platso_58824-Jul-12 23:23
memberplatso_58824-Jul-12 23:23 
GeneralMy vote of 4 Pin
Itz.Irshad8-Jul-12 21:35
memberItz.Irshad8-Jul-12 21:35 
GeneralMy vote of 4 Pin
anver sadat16-May-12 2:41
memberanver sadat16-May-12 2:41 
QuestionXml data with XPath and XmlDocument Pin
Fistum Mekuria25-Apr-12 5:49
memberFistum Mekuria25-Apr-12 5:49 
Hello Michael,

I am currently working on a WinForm application to retriever information from the Xml and display that in the GUI. I am new for Xml and Xpath. I was wondering if you can guide me.

Here is the Xml


<head>

<title>
NOAA's National Weather Service Forecast by 24 Hour Period
</title>
meteorological
forecast
2012-04-23T15:34:17Z


http://graphical.weather.gov/xml/

Meteorological Development Laboratory
Product Generation Branch

http://www.nws.noaa.gov/disclaimer.html
http://www.weather.gov/
http://www.weather.gov/images/xml_logo.gif
http://www.weather.gov/feedback.php

</head>


point1



http://forecast.weather.gov/MapClick.php?textField1=40.39&textField2=-74.11


k-p24h-n1-1
2012-04-24T06:00:00-04:00
2012-04-25T06:00:00-04:00


k-p12h-n2-2
2012-04-24T06:00:00-04:00
2012-04-24T18:00:00-04:00
2012-04-24T18:00:00-04:00
2012-04-25T06:00:00-04:00


k-p1d-n1-3
2012-04-24T06:00:00-04:00
2012-04-25T06:00:00-04:00



Daily Maximum Temperature
60


Daily Minimum Temperature
41


12 Hourly Probability of Precipitation
32
17


Weather Type, Coverage, and Intensity





Conditions Icons

http://www.nws.noaa.gov/weather/images/fcicons/hi_shwrs30.jpg



Watches, Warnings, and Advisories






in a button click I would like to display the temperature of the day max and min. This is how I did it, but it's not working. Please help.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;

namespace Test

{


public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();

}
private XmlDocument doc;
private XmlElement root;
private XmlElement currentTemperature;
private const string PATH = @"..\..\dwmlByDay.xml";
private int current = 0;
private int max;

private void Form2_Load(object sender, EventArgs e)
{
doc = new XmlDocument();
doc.Load(PATH);

//Get root element
root = doc.DocumentElement;

//Determine maximum possible index
max = root.GetElementsByTagName("Temperature").Count - 1;

//Get the record at the current index
currentTemperature = (XmlElement)root.ChildNodes[current];

//Show the record information
ShowDetails(currentTemperature);
}

private void ShowDetails(XmlElement currentTemperature)
{
throw new NotImplementedException();
}




private void button1_Click(object sender, EventArgs e)
{
current = 0;
currentTemperature = (XmlElement)root.ChildNodes[current];
ShowDetails(currentTemperature);
}

private void button2_Click(object sender, EventArgs e)
{
current = max;
currentTemperature = (XmlElement)root.ChildNodes[current];
ShowDetails(currentTemperature);
}


}


}
GeneralMy vote of 4 Pin
Amit kumar pathak31-Mar-12 6:58
memberAmit kumar pathak31-Mar-12 6:58 
Question[My vote of 1] Namespace attribute breaks your example Pin
troybooth17-Feb-12 4:43
membertroybooth17-Feb-12 4:43 
Questionvote 5 Pin
tiktaktoe18-Jul-11 21:00
membertiktaktoe18-Jul-11 21:00 
GeneralMy vote of 5 Pin
YSDen12322-Jun-11 23:39
memberYSDen12322-Jun-11 23:39 
GeneralMy vote of 5 Pin
sailu sirish6-May-11 1:01
membersailu sirish6-May-11 1:01 
GeneralMy vote of 1 Pin
Milos Culic22-Dec-10 0:19
memberMilos Culic22-Dec-10 0:19 
GeneralMy vote of 5 Pin
XtErMiNaToR10224-Nov-10 2:38
memberXtErMiNaToR10224-Nov-10 2:38 
GeneralMy vote of 5 Pin
Dell.Simmons28-Oct-10 16:01
memberDell.Simmons28-Oct-10 16:01 
GeneralGreat for beginners Pin
umerjafer30-Sep-10 8:47
memberumerjafer30-Sep-10 8:47 
GeneralXML and SQL 2005/2008 Express with an XML field Pin
larry Williams31-Aug-10 14:15
memberlarry Williams31-Aug-10 14:15 
GeneralAwesome! Pin
erat1233-Jun-10 5:58
membererat1233-Jun-10 5:58 
GeneralGet value of an element on the basis of two attribute values Pin
Brad North30-Apr-10 3:04
memberBrad North30-Apr-10 3:04 
GeneralPlease go thru another good example. Pin
shijoforum23-Oct-09 6:28
membershijoforum23-Oct-09 6:28 
GeneralThank you Pin
Miko_chan29-Jun-09 12:43
memberMiko_chan29-Jun-09 12:43 
GeneralCan't figure out how to read my xml Pin
sraelgaiznaer14-Jun-09 17:43
membersraelgaiznaer14-Jun-09 17:43 
QuestionGet elements that contain a certain string Pin
fcp14-Jun-09 2:54
memberfcp14-Jun-09 2:54 
Questionhi guys Pin
suhaib198220-May-09 4:07
membersuhaib198220-May-09 4:07 
Questionhow to create xml file using xpaths? Pin
kumarrajt4-May-09 22:13
memberkumarrajt4-May-09 22:13 
GeneralExtracting Attributes of nodes Pin
naeem.akram.malik29-Jan-09 4:27
membernaeem.akram.malik29-Jan-09 4:27 
GeneralXpath Pin
abhilashj12530-Dec-08 23:36
memberabhilashj12530-Dec-08 23:36 
GeneralTHank you Pin
SanShark6-Dec-08 2:25
memberSanShark6-Dec-08 2:25 
GeneralMy vote of 2 Pin
DheerajJain19783-Dec-08 0:59
memberDheerajJain19783-Dec-08 0:59 
GeneralMy vote of 5 Pin
Indrora22-Nov-09 5:04
memberIndrora22-Nov-09 5:04 
GeneralRe: My vote of 5 Pin
Dell.Simmons28-Oct-10 16:01
memberDell.Simmons28-Oct-10 16:01 
GeneralTHANK YOU SSOOOO MUCH...!!! Pin
Melu3-Apr-08 11:26
memberMelu3-Apr-08 11:26 
GeneralBest Article on XML Serialization and Selecting Node Pin
SamTheGreat15-Mar-08 3:44
memberSamTheGreat15-Mar-08 3:44 
QuestionC# code for getting value from XML file Pin
Ritesh Gupta6-Dec-07 21:19
sussRitesh Gupta6-Dec-07 21:19 
Questionwhats the difference between using ReplaceChild and Setting InnerXml of the oldNode? Pin
AnandChavali21-Aug-07 21:26
memberAnandChavali21-Aug-07 21:26 
AnswerRe: whats the difference between using ReplaceChild and Setting InnerXml of the oldNode? Pin
-Rufus-30-Sep-08 9:13
member-Rufus-30-Sep-08 9:13 
GeneralNice Job Pin
Mike Hankey25-Mar-07 14:22
memberMike Hankey25-Mar-07 14:22 
QuestionRestricted editing in xml Pin
Anash P Oommen13-Sep-06 3:30
memberAnash P Oommen13-Sep-06 3:30 
GeneralSelect Distinct Attributes or Nodes Pin
A55imilate29-Jun-06 2:22
memberA55imilate29-Jun-06 2:22 
QuestionRe: Select Distinct Attributes or Nodes Pin
~MyXa~3-Aug-07 10:16
member~MyXa~3-Aug-07 10:16 
AnswerRe: Select Distinct Attributes or Nodes Pin
A55imilate5-Aug-07 21:33
memberA55imilate5-Aug-07 21:33 
GeneralRe: Select Distinct Attributes or Nodes Pin
~MyXa~6-Aug-07 2:09
member~MyXa~6-Aug-07 2:09 
AnswerRe: Select Distinct Attributes or Nodes Pin
~MyXa~6-Aug-07 22:17
member~MyXa~6-Aug-07 22:17 
GeneralNamespaces and nodes not on the root Pin
titltn2113-Dec-05 11:52
membertitltn2113-Dec-05 11:52 
GeneralXPath DataSet Pin
Anonymous12-Oct-05 17:38
sussAnonymous12-Oct-05 17:38 
AnswerRe: XPath DataSet Pin
Gustavo Leal28-Feb-06 3:45
memberGustavo Leal28-Feb-06 3:45 
GeneralSchema Location Pin
meir_rivkin26-Jul-05 3:04
membermeir_rivkin26-Jul-05 3:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 4 Feb 2005
Article Copyright 2005 by Michael Chao
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid