Une solution portable (XPath 1.0 et 2.0) serait:
<xsl:if test="
$currentNode/ancestor::*[generate-id() = generate-id($someNode)]
">
Write this out.
</xsl:if>
Cela se dirige vers l'axe de l'ancêtre et vérifie chaque élément en elle. Si (et seulement si) l'ID unique de l'un des ancêtres correspond à l'ID unique $someNode
, l'ensemble de nœuds résultant n'est pas vide.
Les ensembles de noeuds non vides ont la valeur true et la condition est remplie.
Test - trouver tous les <baz>
qui sont descendant de <foo>
:
<xml>
<foo>
<bar>
<baz>Test 1</baz>
</bar>
</foo>
<baz>Test 2</baz>
</xml>
et
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<xsl:variable name="someNode" select="//foo[1]" />
<!-- test each <baz> node if it has <foo> as a parent -->
<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>
résultats dans
<baz>Test 1</baz>
Notez que si vous faites référence à la réelle curren t noeud, comme je le fais dans le for-each, il n'y a pas besoin d'une variable distincte $currentNode
. Tout XPath est relatif au nœud actuel par défaut.
Une variante serait la méthode descendante. Il est moins efficace que (probablement par plusieurs ordres de grandeur):
<xsl:if test="
$someNode[//*[generate-id() = generate-id($currentNode)]]
">
Write this out.
</xsl:if>
@Erlock: Merci beaucoup pour l'aide. A travaillé un régal. –