Yesterday I discovered that the XPath expression "/customers/customer" is not an absolute expression even though it looks like one (because it starts with a slash).
I learned this the hard way after struggling with an iteration over an XSLT 2.0 sequence.
The XSLT snippet
<xsl:for-each select="(1 to 3)"> <xsl:value-of select="customer"/> </xsl:for-each>
does not output the value of the element customer 3 times. Instead it generates the following error message:
Cannot select a node here: the context item is an atomic value
This makes sense because the XSLT 2.0 spec clearly states:
When the context item is an atomic value, there is no context node: its value is an empty sequence. The context node is returned by the XPath expression self::node(), and it is used as the starting node for all relative path expressions.
If you change the XSLT snippet to use an 'absolute' expression
<xsl:for-each select="(1 to 3)"> <xsl:value-of select="/customers/customer"/> </xsl:for-each>
it turns out that the error does not disappear. How is this possible?
I have found a clear explanation by Michael Kay:
Because "absolute paths" are not absolute at all: they select relative to
the root of the tree containing the context node. You've got to know which
document to look in.
A workaround was given in the same thread:
<xsl:variable name="tmp" select="/customers"/> <xsl:for-each select="(1 to 3)"> <xsl:value-of select="$tmp/customer"/> </xsl:for-each>
This will give you the expected output: 3 times the value of the element customer.

1 Comment
Fantastically clear.
Submitted by Fab on
Fantastically clear.
Add new comment