AxisSpecifier and Variables

October 5, 2004 in XML/XSLT | Comments (0)

Sometimes what should be easy becomes hard, and I find myself, after the solution is discovered, going, “Well, duh.” Seems if you go in with a bad assumption you fall into this trap, and until you can shake the assumption you stay stuck.

In XSLT, the AxisSpecifier lets you choose which axis you want to search from a particular node. In my particular case, I was attempting to find the next sibling of an element in the XML input document. The axis specifier following-sibling::* will return any following sibling elements for you. If you only want the next one, you need to qualify it as following-sibling::*[1].

Now, the AxisSpecifier, like any other XSL element, assumes that you are operating on the current or context node. What we had done was to pass in a node set in a parameter to a named template, and we wanted to retrieve the next sibling of that node, regardless of what the context node was.

Here’s what works:

<xsl:template name="process-sibling">
 <xsl:param name="node" select="current()"/>
 <xsl:variable name="next-node" select=$node/following-sibling::*[1]"/>
 <xsl:copy-of select="$next-node"/>

We kept trying to go the other way around, like this, as if following-sibling was some kind of function call:

 <xsl:variable name="next-node" select=following-sibling::$node"/>

Looking back, it makes all the sense in the world. It’s funny how long you can stay stuck until you change your perspective.

Notice that you need to copy the sibling element into a variable before you can access its attributes. You cannot do this:

 <xsl:variable name="next-node" select=$node/following-sibling::*[1]/@some-attribute"/>

This is what works:

<xsl:variable name="next-node" select=$node/following-sibling::*[1]"/>
<xsl:variable name="some-attribute" select=$next-node/@some-attribute"/>

Comments are closed.