Une solution similaire à celle de Teun, mais permettant "personne" éléments dans pas immédiat relation parent-enfant est le suivant:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="//person[not(person)]"/>
</xsl:template>
<xsl:template match="person" name="tPerson">
<xsl:value-of select="concat(@name,'
')"/>
<xsl:apply-templates select=
"ancestor::person[1]"/>
</xsl:template>
</xsl:stylesheet>
Lorsqu'il est appliqué sur le document XML fourni à l'origine, le résultat correct est produit:
Shemp
Curly
Moe
Larry
Il est bon de savoir que de nombreux problèmes de ce type ne nécessitent pas récursion du tout! Cette transformation produit exactement le même résultat et implique que l'itération:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//person[not(person)]">
<xsl:for-each select="ancestor::person | .">
<xsl:sort select="position()" order="descending"/>
<xsl:value-of select="concat(@name,'
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Prenez note le genre qui assure l'ordre inverse du traitement.
@Bruno Tyndall J'ai testé cette transformation avec .NET 2.0 + XslCompiledTransform. Cela devrait aussi fonctionner avec XslTransform plus ancien. –