Reputation: 3046
Given this input:
<?xml version="1.0"?><catalog>
<book>
<autho>Gambardella, Matthew</author>
</book>
<book>
<author>Ralls, Kim</author>
</book>
</catalog>
and this XSLT 2.0 stylesheet
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<out>
<xsl:apply-templates/>
</out>
</xsl:template>
<xsl:template match="catalog">
<xsl:for-each select="book">
<text>
Current node: <xsl:value-of select=" current()/name()"/>
Context node: <xsl:value-of select="./name()"/>
</text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
why is the output not:
<?xml version="1.0" encoding="UTF-8"?><out><text>
Current node: catalog
Context node: book</text><text>
Current node: catalog
Context node: book</text></out>
but instead:
<?xml version="1.0" encoding="UTF-8"?><out><text>
Current node: book
Context node: book</text><text>
Current node: book
Context node: book</text></out>
I thought current()
refers back to the node the template matches and I can use it to always refer back to that node?
Upvotes: 1
Views: 232
Reputation: 3229
It does make a difference whether you use .
or current()
when dealing with XPath expressions with square brackets. By using an opening square bracket, you change the context, and .
will relate to the expression immediately before the brackets, whereas current()
is not affected by the context change.
With <xsl:for-each>
, things are different. It also changes the context, but .
and current()
are both affected.
The thing you want can be achieved by storing .
in a variable before the for-each loop starts:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<out>
<xsl:apply-templates/>
</out>
</xsl:template>
<xsl:template match="catalog">
<xsl:variable name="context" select="."/>
<xsl:for-each select="book">
<text>
Current node: <xsl:value-of select="$context/name()"/>
Context node: <xsl:value-of select="./name()"/>
</text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2