I. Перевод псевдокода
Ваш псевдокод переводит 1: 1 в это XSLT-преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:for-each select="/t/m/n/p">
<xsl:choose>
<xsl:when test="not(subPath)">
<a><xsl:value-of select="x"/></a>
<b><xsl:value-of select="y"/></b>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="subPath">
<a><xsl:value-of select="../x"/></a>
<b><xsl:value-of select="../y"/></b>
<c><xsl:value-of select="z"/></c>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
при применении к этому XML-документу (в вопросе такой документ не предоставляется !!!):
<t>
<m>
<n>
<p>
<x>1</x>
<y>2</y>
<subPath>
<z>3</z>
</subPath>
<subPath>
<z>4</z>
</subPath>
</p>
</n>
</m>
</t>
желаемый, правильный результат получается :
<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>
II. Рефакторинг
Это преобразованное эквивалентное преобразование, в котором не используются xsl:for-each
или какие-либо явные условные инструкции :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="p[not(subPath)]" name="processP">
<xsl:param name="pNode" select="."/>
<a><xsl:value-of select="$pNode/x"/></a>
<b><xsl:value-of select="$pNode/y"/></b>
</xsl:template>
<xsl:template match="p/subPath">
<xsl:call-template name="processP">
<xsl:with-param name="pNode" select=".."/>
</xsl:call-template>
<c><xsl:value-of select="z"/></c>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
при применении к тому же XML-документу (см. Выше), снова получается тот же правильный результат :
<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>
Do note :
Шаблоны / сопоставление с образцом, чтобы избежать использования явных условных инструкций. Это самый мощный XSLT-специфичный шаблон проектирования.
Повторяющегося кода нет.
Каждый шаблон точно соответствует узлу, который он должен обрабатывать, при точно требуемых условиях.
Код первого шаблона используется повторно, также давая ему имя, чтобы его можно было явно вызывать. Таким образом исключается дублирование кода.