0

これは私のXMLおよびXSLTコードです

<root>
    <act>
        <acts id>123</acts>
    </act>
    <comp>
        <comps id>233</comps>
    </comp>
</root>


<xsl:for-each select="act/acts">
    <xsl:variable name="contactid" select="@id"/>
    <xsl:for-each select="root/comp/comps">
        <xsl:variable name="var" select="boolean(contactid=@id)"/>
    </xsl:for-each>
    <xsl:choose>
        <xsl:when test="$var='true'">
          . . . do this . . .
        </xsl:when>
        <xsl:otherwise>
          . . . do that . . .
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>

trueまたはfalseを動的に割り当てて、ブールテストのvar内部で使用したいと思います。私はこれがまた<xsl:choose>取り除くためのより良い解決策を見つけるのに役立つことを願っていますfor-each

4

2 に答える 2

3

最初に注意することは、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:choosexsl: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ノードのより具体的なテンプレートが優先されることに注意してください。

于 2012-04-19T07:25:27.623 に答える
1

xmlファイルにいくつかのエラーがありますが、意味するところは次のとおりです。

<root>
    <act><acts id="123"></acts></act>
    <comp><comps id="233"></comps></comp>
</root>

完全な解決策は次のとおりです。

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="root/comp/comps"/>  
        </doc>
    </xsl:template>

    <xsl:template match="root/comp/comps"> 
        <xsl:variable name="compsid" select="@id"></xsl:variable>
        <xsl:choose>
            <xsl:when test="count(/root/act/acts[@id=$compsid])&gt;0">Do This</xsl:when>
            <xsl:otherwise>Do That</xsl:otherwise>
        </xsl:choose>
    </xsl:template> 

</xsl:stylesheet>
于 2012-04-18T18:58:48.083 に答える