Example 2-8. Location paths
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<body>
<h1>XPath Examples</h1>
The third president was:
<ul>
<xsl:apply-templates select="presidents/president[position( ) = 3]/name"/>
</ul>
Presidents without vice presidents were:
<ul>
<xsl:apply-templates
select="presidents/president[count(vicePresident) = 0]/name"/>
</ul>
Presidents elected before 1800 were:
<ul>
<xsl:apply-templates
select="presidents/president[term/@from < 1800]/name"/>
</ul>
Presidents with more than one vice president were:
<ul>
<xsl:apply-templates
select="descendant::president[count(vicePresident) > 1]/name"/>
</ul>
Presidents named John were:
<ul>
<xsl:apply-templates
select="presidents/president/name[child::first='John']"/>
</ul>
Presidents elected between 1800 and 1850 were:
<ul>
<xsl:apply-templates
select="presidents/president[(term/@from > 1800) and
(term/@from < 1850)]/name"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="name">
<li>
<xsl:value-of select="first"/>
<xsl:text> </xsl:text>
<xsl:value-of select="middle"/>
<xsl:text> </xsl:text>
<xsl:value-of select="last"/>
</li>
</xsl:template>
</xsl:stylesheet>
In the first <xsl:apply-templates> element,
the location path is as follows:
presidents/president[position( ) = 3]/name
This path consists of three location steps separated by slash
(/) characters, but the final step is what we want
to select. This path is read from left to right, so it first selects
the <presidents> children of the current
context. The next step is relative to the
<presidents> context and selects all
<president> children. It then filters the
list according to the predicate. The third
<president> element is now the context, and
its <name> children are selected. Since each
president has only one <name>, the template
that matches "name" is instantiated only once.
This location path shows how to perform basic numeric comparisons:
presidents/president[term/@from < 1800]/name
Since the less-than (<) character cannot appear
in an XML attribute value, the < entity
must be substituted. In this particular example, we use the
@ abbreviated syntax to represent the attribute
axis.