Вот наиболее общий способ выполнения «обратной рекурсии» , который не зависит от этой конкретной проблемы и может использоваться в самых разных задачах.
Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:call-template name="backwardsRecursion">
<xsl:with-param name="pList" select="//person"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="backwardsRecursion">
<xsl:param name="pList"/>
<xsl:if test="$pList">
<xsl:apply-templates select="$pList[last()]"/>
<xsl:call-template name="backwardsRecursion">
<xsl:with-param name="pList" select=
"$pList[position() < last()]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="person">
<xsl:value-of select="concat(@name,'
')"/>
</xsl:template>
</xsl:stylesheet>
при применении к первоначально предоставленному XML-документу дает желаемый результат :
Shemp
Curly
Moe
Larry
Обратите внимание , что вызывается универсальный шаблон с именем "backwardsRecursion", который действительно реализует обратную рекурсию. Этот шаблон не знает ничего об узлах, которые он обрабатывает, или о том, как они будут обрабатываться .
Таким образом, этот шаблон можно использовать в любой ситуации, когда требуется обратная рекурсивная обработка.