最初に注意することは、XSLTの変数は不変であり、一度初期化すると変更できないことです。XSLTの主な問題は、xsl:for-eachブロック内で変数を定義するため、そのブロックのスコープ内にのみ存在することです。これはグローバル変数ではありません。xsl:for-each内でのみ使用できる新しい変数が毎回定義されます
XSLTを見ると、 acts要素を反復処理し、 comps要素が同じ値で存在するかどうかに応じて特定のアクションを実行するように見えます。別のアプローチは、次のように、comps要素を検索するためのキーを定義することです。
<xsl:key name="comps" match="comps" use="@id" />
次に、 comps要素がそのように存在するかどうかを簡単に確認できます( acts要素に配置されていると仮定します)。
<xsl:choose>
<xsl:when test="key('comps', @id)">Yes</xsl:when>
<xsl:otherwise>No</xsl:otherwise>
</xsl:choose>
これが完全なXSLTです
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="comps" match="comps" use="@id" />
<xsl:template match="/root">
<xsl:apply-templates select="act/acts" />
</xsl:template>
<xsl:template match="acts">
<xsl:choose>
<xsl:when test="key('comps', @id)"><res>Yes</res></xsl:when>
<xsl:otherwise><res>No</res></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
次の(整形式の)XMLに適用した場合
<root>
<act>
<acts id="123"/>
</act>
<comp>
<comps id="233"/>
</comp>
</root>
以下が出力されます
いいえ
ただし、 xsl:chooseやxsl:ifなどの条件ステートメントの使用を避けるためにXSLTで使用することが望ましい場合がよくあります。代わりに、テンプレートマッチングを利用するようにXSLTを構造化できます。これが別のアプローチです
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="comps" match="comps" use="@id" />
<xsl:template match="/root">
<xsl:apply-templates select="act/acts" />
</xsl:template>
<xsl:template match="acts[key('comps', @id)]">
<res>Yes</res>
</xsl:template>
<xsl:template match="acts">
<res>No</res>
</xsl:template>
</xsl:stylesheet>
同じXMLに適用すると、同じ結果が出力されます。コンプが存在する場合に一致する場合は、 actsノードのより具体的なテンプレートが優先されることに注意してください。