How to search XML content with XPath in C#

The GetElementsByTagName() method illustrated in the article How to search XML content with XmlDocument in C# is fairly limited. It allows you to search based on the name of an element only. You can’t filter based on other criteria, such as the value of the element or attribute content. In these cases you can use XPath standard that allows you to retrieve the portions of a document that interest you.

XPath uses a pathlike notation. For example, the path / identifies the root of an XML document, and /BooksList identifies the root <BooksList> element. The path /BooksList/Book selects every <Book> element inside the <BooksList>. Finally, the period (.) always selects the current node. In addition, the path // is a recursive path operator that searches all the descendants of a node. If you start a path with the // characters, the XPath expression will search the entire document for nodes. These ingredients are enough to build many basic templates, although the XPath standard also defines special selection criteria that can filter out only the nodes in which you are interested. The next table provides a method overview of XPath characters.

 

ExpressionMeaning
/Searches for child nodes. If you place / at the beginning of an XPath expression, it creates an absolute path that starts from the root node. /BooksList/Book selects all <Book> elements that are children of the root <BooksList> element.
//Searches for child nodes recursively, digging through all the nested layers of nodes. If

you place // at the beginning of an XPath expression, it creates a relative path that selects nodes anywhere. //Book/Title selects all the <Title> elements that are descendants of a <Book> element.

@Selects an attribute of a node. /BooksList/Book/@ISBN-13 selects the method attribute named ISBN-13 from all <Book> elements.
*Selects any element in the path. /BooksList/Book/* selects all the child nodes in the

<Book> element (which include <Authorr>, <Price>, and <Available> in this example).

|Combines multiple paths. /BooksList/Book/Author | BooksList/Book/Price selects both

the <Author> and <Price> elements in the <Book> element.

.Indicates the current (default) node.
..Indicates the parent node. If the current node is <Author>, then .. refers to the <Book>

node.

[]Defines selection criteria that can test a contained node or attribute value. /BooksList/Book[Title=’ Harry Potter and the Deathly Hallows’] selects the <Book> elements that contain a <Book> element with the indicated attribute value. BooksList/DVD[@Autor=’ Walter Isaacson ‘] selects the <Book> elements with the indicated value. You can use the and keyword and the or keyword to combine criteria.
starts-withThis method function retrieves elements based on what text a contained element starts

with. /BooksList/DVD[starts-with(Title, ‘H’)] finds all <Book> elements that have a <Title> element that contains text that starts with the letter H.

positionThis function retrieves elements based on position, using 1-based counting. /BooksList/Book[position()=2] selects the second <Book> element. You can also use the

shorthand /BooksList/DVD[2].

countThis function counts the number of elements with the matching name. count(Book) returns the number of <Book> elements.

 

You can execute XPath expression in .NET, by using the Select() method of the XPathNavigator or the SelectNodes() or SelectSingleNode() method of the XmlDocument class. The following code uses this technique method to retrieve specific information:

 

// Load the XML file.

string xmlFile = Server.MapPath(“BooksList.xml”);

XmlDocument doc = new XmlDocument();

doc.Load(xmlFile);

 

// Retrieve the title of every science-fiction movie.

XmlNodeList nodes =

doc.SelectNodes(“/BooksList/Book/Title[../@ISBN-13=’978-0545139700′]”);

 

// Display the titles.

StringBuilder str = new StringBuilder();

foreach (XmlNode node in nodes)

{

str.Append(“Found: <b>”);

// Show the text contained in this <Title> element.

str.Append(node.ChildNodes[0].Value);

str.Append(“</b><br />”);

}

lblXml.Text = str.ToString();