Check with Adam for a very quick first answer.
Just add some details:
Your expected result does not match your words. the root element is also the ancestor of the node, and the document is also the ancestor of the node.
ancestor::node()
... will return the sequence in the following order:
item[@title='b']item[@title='a']root element (aka document element)- root node
/
To get the specific result that you specified, you need:
ancestor::item/.
Effect/. consists in changing the order of the document forward order. Native ancestor order :: - reverse document order.
Update: Illustration of dots made in the comments feed.
This style sheet (with OP input) ...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:for-each select="//item[@title='c']"> <xsl:value-of select="ancestor::item[1]/@title" /> <xsl:value-of select="ancestor::item[2]/@title" /> </xsl:for-each> </xsl:template> </xsl:stylesheet>
... displays "ba" illustrating the point at which the ancestor :: is indeed the inverse axis. And yet this style sheet ...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:for-each select="//item[@title='c']"> <xsl:value-of select="(ancestor::item/@title)[1]" /> <xsl:value-of select="(ancestor::item/@title)[2]" /> </xsl:for-each> </xsl:template> </xsl:stylesheet>
... has the opposite result "ab". This is instructive because it shows that in XSLT 1.0 (not so in XSLT 2.0), the brackets remove the inverse and become documented node-set.
The OP asked about the conversion of something like ....
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:for-each select="//item[@title='c']"> <xsl:for-each select="ancestor::item"> <xsl:value-of select="@title" /> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
This returns ab (in XSLT 2.0 it returns "ba"). What for? Because in XSLT 1.0, the xsl: for-each command ignores the back axis of the axis and processes in document order (unless the xsl: sort instruction is specified otherwise).