A solution similar to that of teun, but allowing "person" elements to be in not immediate parent-child relationship is the following:
<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>
When applied on the originally provided XML document, the correct result is produced:
Shemp
Curly
Moe
Larry
It is good to know that many problems of this type do not require recursion at all!
This transformation produces exactly the same result and only involves iteration:
<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>
Do note the sort that ensures the reverse order of processing.