From Edutechwiki - Reading time: 16 minXPath is a language for addressing parts of an XML document. Basic understanding of XPath is needed for XSLT and XQuery programming. In this piece, we shall show how to create XSLT stylesheets that use some moderately complex XPath expressions
Tip: Read the free O'Reilly book: http://commons.oreilly.com/wiki/index.php/XPath_and_XPointer
Learning Objectives
Prerequisites
Next steps
Materials
Disclaimer
XPath is a language for addressing parts of an XML document, In support of this primary purpose, it also provides basic facilities for manipulation of strings, numbers and booleans.
Its 2.0 editition was described as “XPath 2.0 is an expression language that allows the processing of values conforming to the data model defined in XQuery/XPath Data Model (XDM). The data model provides a tree representation of XML documents as well as atomic values such as integers, strings, and booleans, and sequences that may contain both references to nodes in an XML document and atomic values. The result of an XPath expression may be a selection of nodes from the input documents, or an atomic value, or more generally, any sequence allowed by the data model. The name of the language derives from its most distinctive feature, the path expression, which provides a means of hierarchic addressing of the nodes in an XML tree.” (XML Path Language (XPath) 2.0 ,W3C Recommendation 23 January 2007, retrieved 16:38, 9 February 2010 (UTC).
In plain English, XPath allows retrieving parts of an XML document. XPath expressions can be as simple as the name of an XML element or so complicated that only experts can understand it ....
XPath 1.0 is used by XSLT 1.0, i.e. the XSLT processor included in virtually every web browser as of Jan 2010 and since the early 2000's in IE/Mozilla.
XPath 2.0 is a superset of XPath 1.0 and is used by XSLT 2.0, XQuery and other specifications.
Each time a given XSLT or XQuery instruction needs to address (refers to) parts of an XML document, we use XPath expressions. XPath expressions also can contain functions, simple math and boolean expressions.
Within XSLT, XPath expressions are typicially used in match, select and test attributes:

Below is an XQuery example taken from the XQuery tutorial - basics
for $t in fn:doc("catalog09.xml")//c3msbrick
let $n := count($t//c3mssoft)
where ($n > 1)
order by $n
return <result> {$t/title/text()} owns {$n} bricks </result>
Most XML editors will display the XPath of a selected element. In addition, you can search with XPath expressions, i.e. test an expression that you then would use in your XSLT or XQuery code.
Below is a screenshot of the XML Exchanger editor. As you can see we entered the //participant expression in the search box. The result is a so-called node-set that is displayed in the XPath pane at the bottom.

XPath expressions can be quite simple or very complex. An Xpath expression may include a location path (i.e. "where to look for"), node tests (i.e. identifying a node) and predicates(i.e. additional tests).
There are two notations for location paths.
(1) abbreviated
This simple notation allows to locate itself, children, parents, attributes and combinations of these. Going up or down is called an axis. The abbreviated form has limited axis.
(2) unabbreviated
Unabbreviated location path allows to search in more axis then just parents, children, and siblings.
The abbreviated location path look a bit like file paths. E.g. the following expression:
/section/title
means: find all title nodes below section nodes
Syntax overview of the primary (relatively simple) XPath expressions
The picture below is not entirely correct, i.e. the "green" elements are part of the so called node-test
The result of an Xpath expression can be various data types, e.g. sets of nodes, a single node, a number, etc. Most often the result, is a set of nodes.
Below, we present a few expressions for locating nodes using the simple abbreviated syntax. As we said before, location paths can be horribly complex, but simple location path look a bit like file path that you would use in HTML links or in an operating system like Unix, Windows or MacOS.
Let us recall that we use the same XML document in most examples. You can download the file or look at a wiki page:
<?xml version="1.0"?>
<project>
<title>The Xpath project</title>
<participants>
<participant>
<FirstName>Daniel</FirstName>
<qualification>8</qualification>
<description>Daniel will be the tutor</description>
<FoodPref picture="dolores_001.jpg">Sea Food</FoodPref>
</participant>
<participant>
<FirstName>Jonathan</FirstName>
<qualification>5</qualification>
<FoodPref picture="dolores_002.jpg">Asian</FoodPref>
</participant>
<participant>
<FirstName>Bernadette</FirstName>
<qualification>8</qualification>
<description>Bernadette is an arts major</description>
</participant>
<participant>
<FirstName>Nathalie</FirstName>
<qualification>2</qualification>
</participant>
</participants>
<problems>
<problem>
<title>Initial problem</title>
<description>We have to learn something about Location Path</description>
<difficulty level="5">This problem should not be too hard</difficulty>
</problem>
<solutions>
<item val="low">Buy a XSLT book</item>
<item val="low">Find an XSLT website</item>
<item val="high">Register for a XSLT course and do exercices</item>
</solutions>
<problem>
<title>Next problem</title>
<description>We have to learn something about predicates</description>
<difficulty level="6">This problem is a bit more difficult</difficulty>
</problem>
<solutions>
<item val="low">Buy a XSLT book</item>
<item val="medium">Read the specification and do some exercises</item>
<item val="high">Register for a XPath course and do exercices</item>
</solutions>
</problems>
</project>
We would like to get a simple list of problem titles
XSLT template (file: xpath-jungle-1.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/project">
<html>
<body bgcolor="#FFFFFF">
<h1><xsl:value-of select="title" /></h1>
Here are the titles of our problems: <ul>
<xsl:apply-templates select="problems/problem" />
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="problems/problem">
<li><xsl:value-of select="title" /></li>
</xsl:template>
</xsl:stylesheet>
This second rule will be triggered by the first rule, because problems/problem is indeed a location that can be found in project element. The processor then can extract the value of the title element.
Alternatively we could have written this rule as:
<xsl:template match="problems/problem/title">
<li><xsl:apply-templates/></li>
</xsl:template>
or
<xsl:template match="problems/problem/title">
<li><xsl:value-of select="."/></li>
</xsl:template>
<html>
<body bgcolor="#FFFFFF">
<h1>The Xpath project</h1>
Here are the titles of our problems:
<ul>
''<li>Initial problem</li>''
''<li>Next problem</li>''
</ul>
</body>
</html>
Live example:
Of course, XPath also also to locate attributes. We shall show the principle, using a few examples.
(1) To find an attribute of a child element in the current context use:
Example:
(2) Find attributes of an element in a longer location path starting from root
/element_name/element_name/@attribute_name
Example:
/project/problems/solutions/item/@val
(3) Find attributes in the whole document: //@attribute_name
As you can see you can combine element location with attribute identification.
Same as above
Display a list of First Names plus their food preferences
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>What do we know about our participants ?</h1>
Here are some food preferences: <ul>
<xsl:apply-templates select=".//participant" />
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="participant">
<li><xsl:value-of select="FirstName"/>
<xsl:apply-templates select="FoodPref"/>
</li>
</xsl:template>
<xsl:template match="FoodPref">
prefers <xsl:value-of select="."/>.
<img src="{@picture}"/> <br clear="all"/>
</xsl:template>
</xsl:stylesheet>
<h1>What do we know about our participants ?</h1>
Here are some food preferences:
<ul>
<li>Daniel prefers Sea Food.
<img src="dolores_001.jpg"><br clear="all"></li>
<li>Jonathan
prefers Asian.
<img src="dolores_002.jpg"><br clear="all"></li>
<li>Bernadette</li>
<li>Nathalie</li>
</ul>
Live example:
Example: XSLT includes two built-in default rules. They rely on using these wildcards.
This rule applies to the document root and all other elements
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Text and attribute values are just copied
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
Let us now scale up a bit.
/project/participants/participant[2] /project/participants/participant[2]/FirstName
//difficulty[@level]
- * div mod
5 mod 2 returns 1, as will "7 mod 2" and "3 mod 2"
<xsl:template match="'//item[@val='low']">
<xsl:value-of select="." />
</xsl:template>
Usually expressions also contain functions as we shall see below, examples:
author [(last() - 4) <= position()) and (position() <= last())]
"//Participant[string-length(FirstName)>=8]"
The following example will retrieve the following:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Retrieve selected elements</h1>
Here is the name of participant two:
<ul><li><xsl:value-of select=".//participant[2]/FirstName"/></li></ul>
Here are all participant's firstnames that have a food preference:
<ul><xsl:apply-templates select=".//participant[FoodPref]"/></ul>
Here are all items that have a value of "high"
<ul><xsl:apply-templates select=".//item[@val='high']"/></ul>
</body>
</html>
</xsl:template>
<xsl:template match="participant">
<li><xsl:value-of select="FirstName"/></li>
</xsl:template>
<xsl:template match="item">
<li><xsl:value-of select="."/></li>
</xsl:template>
</xsl:stylesheet>
<html>
<body bgcolor="#FFFFFF">
<h1>Retrieve selected elements</h1>
Here is the name of participant two:
<ul>
<li>Jonathan</li>
</ul>
Here are all participant's firstnames that have a food preference:
<ul>
<li>Daniel</li>
<li>Jonathan</li>
</ul>
Here are all items that have a value of "high"
<ul>
<li>Register for a XSLT course and do exercices</li>
<li>Register for a XPath course and do exercices</li>
</ul>
</body>
</html>
Live example:
Below is a more complex example. One in short notation and the other (to do) in it equivalent long notations:
/outputTree/command/pivotTable/dimension//category[@text='Measurement']/dimension/category/cell[@text='Nominal']
XPath defines a certain number of functions. You can recognize a function because it has appended "()".
Functions are programming constructs that will return various kinds of informations, e.g.
It is not obvious to understand what all of these functions do. For example, there are restrictions on how you can use functions (stick to examples or the reference)
<xsl:strip-space elements="name_of_the_parent_node"/>
We got <xsl:value-of select="count(//problem)"/> problems,
//Participant[starts-with(Firstname,'Berna')]"
//Participant[contains(FirstName,'nat')]
<participant><FirstName>Daniel</FirstName>
''<qualification>8</qualification>''
</participant>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Qualification level of participants</h1>
Average is
<xsl:value-of select="sum(.//participant/qualification) div count(.//participant/qualification)"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<html>
<body bgcolor="#FFFFFF">
<h1>Qualification level of participants</h1>
Average is
5.75
</body>
</html>
Live example:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body bgcolor="#FFFFFF">
<h1>Do we have a "nat" ?</h1>
First Names that contain "nat":
<ul><xsl:apply-templates select=".//participant[contains(FirstName,'nat')]"/></ul>
First Names that contain "nat" and "Nat":
<ul><xsl:apply-templates select=".//participant[contains(translate(FirstName,'N','n'),'nat')]"/></ul>
</body>
</html>
</xsl:template>
<xsl:template match="participant">
<li><xsl:value-of select="FirstName"/></li>
</xsl:template>
</xsl:stylesheet>
Live example
Union Xpaths combine more than one XPath (and all the resulting nodes are returned). A typical example that we already introduced above is the default rule which means that the template matches either the root element (i.e. "/" or just any element),
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
Often, this construct is used to simplify apply-templates or even templates themselves. E.g. the following rules applies to both "description" and "para" elements.
<xsl:template match="para|description">
<p><xsl:apply-templates/></p>
</xsl:template>
|
Syntax |
(Type of path) |
Example path |
Example matches |
|---|---|---|---|
|
name |
child element name |
project |
<project> ...... </project> |
|
/ |
child / child |
project/title |
<project> <title> ... </title> |
|
/ |
(root element) | ||
|
// |
descendant |
project//title |
<project><problem> <title>....</title> |
|
//title |
<root>... <title>..</title> (any place) | ||
|
* |
"wildcard" |
*/title |
<bla> <title>..</title> and <bli> <title>...</title> |
|
| |
"or operator |
title|head |
<title>...</title> or <head> ...</head> |
|
*|/|@* |
All elements: root, children and attributes | ||
|
. |
current element |
. |
|
|
../ |
parent element |
../problem |
<project> |
|
@attr |
attribute name |
@id |
<xyz id="test">...</xyz> |
|
element/@attr |
attribute of child |
project/@id |
<project id="test" ...> ... </project> |
|
@attr='value' |
value of attribute |
list[@type='ol'] |
<list type="ol"> ...... </list> |
|
position() |
position of element |
position() |
|
|
last() |
number of elements within a context |
last() position()!=last() |
|
Important:
Good code:
Bad code:
Example fragment where position in a list is used to compute position on the screen with SVG in HTML5:
<xsl:strip-space elements="list"/>
<xsl:template match="list">
<rect x="10" y="105" width="{10 * count(item)}"
height="5" fill="black" stroke="red"/>
<xsl:apply-templates/>
</xsl:template>
Live example: