これは単純で短い解決策です: 2 つのテンプレートのみで、明示的な条件付き命令はありません:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:names>
<n short="b">bold</n>
<n short="i">italic</n>
<n short="u">underline</n>
</my:names>
<xsl:variable name="vNames" select="document('')/*/my:names/*"/>
<xsl:template match=
"node()[not(contains('+b+i+u+', concat('+',name(),'+')))]
/*[contains('+b+i+u+', concat('+',name(),'+'))]
">
<emphasis>
<xsl:apply-templates select="." mode="emph"/>
</emphasis>
</xsl:template>
<xsl:template mode="emph"
match="*[contains('+b+i+u+', concat('+',name(),'+'))]">
<xsl:attribute name="{$vNames[@short=name(current())]}">yes</xsl:attribute>
<xsl:apply-templates select="node()" mode="emph"/>
</xsl:template>
</xsl:stylesheet>
この変換が次の XML ドキュメントに適用される場合:
<test>
<b>bold</b>
<i>Italic</i>
<b><i>bold Italic</i></b>
<u><b><i>bold Italic underline</i></b></u>
</test>
必要な正しい結果が生成されます。
<emphasis bold="yes">bold</emphasis>
<emphasis italic="yes">Italic</emphasis>
<emphasis bold="yes" italic="yes">bold Italic</emphasis>
<emphasis underline="yes" bold="yes" italic="yes">bold Italic underline</emphasis>