The portable (XPath 1.0 and 2.0) solution would be:
<xsl:if test=" $currentNode/ancestor::*[generate-id() = generate-id($someNode)] "> Write this out. </xsl:if>
This raises the axis of the ancestor and checks each element in it. If (and only if) the unique identifier of one of the ancestors corresponds to the unique identifier $someNode , then the resulting node -set is not empty.
Non-empty node-sets evaluate to true, so the condition is met.
Test - find all <baz> that are descendants of <foo> :
<xml> <foo> <bar> <baz>Test 1</baz> </bar> </foo> <baz>Test 2</baz> </xml>
and
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:template match="/"> <xsl:variable name="someNode" select="//foo[1]" /> <xsl:for-each select="//baz"> <xsl:if test=" ancestor::*[generate-id() = generate-id($someNode)] "> <xsl:copy-of select="." /> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
leads to
<baz>Test 1</baz>
Note that if you are referring to the current current node, as I do in for-each, there is no need for a separate $currentNode variable. All XPath defaults to the current node.
The option will be from top to bottom. It is less effective, though (probably several orders of magnitude):
<xsl:if test=" $someNode[//*[generate-id() = generate-id($currentNode)]] "> Write this out. </xsl:if>
source share