I have the following working 100% correctly. However to satisfy my curiosity... is there a way to achieve the same without declaring the currentID variable? Is there some way to reference it from within the Xpath "test" condition?
The xpath query in the condition must refer to 2 @id attributes to see if they match.
Here's the code:
<xsl:variable name="currentID" select="@id" />
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node [@id = $currentID])>0">descendant-selected </xsl:if>
</xsl:attribute>
Since you select the $currentID
from the context node:
<xsl:variable name="currentID" select="@id" />
you can use the current()
function, which always refers to the XSLT context node:
<xsl:attribute name="class">
<xsl:if test="count($currentPage/ancestor::node[@id = current()/@id]) > 0]">
<xsl:text>descendant-selected </xsl:text>
</xsl:if>
</xsl:attribute>
This way you don't need a variable.
A few other notes:
<xsl:text>
like shown above. This gives you more freedom to format your code and avoid overly long lines.count() > 0
, simply selecting the nodes is sufficient. If none exist, the empty node-set is returned. It always evaluates to false, while non-empty node-sets always evaluate to true.If you refer to nodes by @id
regularly in your XSL stylesheet, an <xsl:key>
would become beneficial:
<xsl:key name="kNodeById" match="node" use="@id" />
<!-- ... -->
<xsl:attribute name="class">
<xsl:if test="key('kNodeById', @id)">
<xsl:text>descendant-selected </xsl:text>
</xsl:if>
</xsl:attribute>
The above does not need current()
since outside of an XPath predicate, the context is unchanged. Also, I don't count()
the nodes, since this is redundant (as explained).