I have a document that looks something like
<root>
<element>
<subelement1 />
<subelement2 />
</element>
<element>
<subelement2 />
<subelement1 />
</element>
</root>
In my XSLT sheet in the context of /element[2]/[someNode] I want to get a number that represents the distance of /element[1]/[someNode] (ie, the number of preceding siblings of /element1/[someNode]). For example, in the context of /element[2]/subelement1 I’d like to have some way to get the number 2, the distance from /element[1] to /element[1]/subelement2. I only ever need the distance of the given node name from the first instance of <element>.
Intuitively I thought I could construct this like
<xsl:variable name="nodename" select="name()" />
<xsl:value-of select="/element[1]/$nodename/preceding-sibling::*" />
but unfortunately this sheet doesn’t compile. Is what I’m trying to achieve possible in XSLT?
You cannot use an XSLT variable as the axis of an XPATH statement, but you can use it in a predicate filter. So, if you were to match on any element (i.e.
*) and then restrict it to elements who’s name() is equal to the value stored in your variable (i.e.*[name()=$nodename]) the XPATH will be valid.The XPATH you were constructing would return the value of the matching element. If you want to return how many elements match that pattern, you can use the
count()function.Your example XML has a document element
<root>, but your XPATH does not include<root>.This returns the number of preceding-sibling elements using the variable assigned by the context node:
You could eliminate the variable and just use: