0

次の atm のような XSLT があります。

<xsl:template match="Root">           
<xsl:for-each select="Worksheettype[@name='DubieuzeDebiteurenApp']">
  <xsl:for-each select="Types/Sub/*">        
    <xsl:for-each select="./*">
      <xsl:value-of select="ancestor::Worksheettype/@TypeId"/> ; <xsl:value-of select="local-name(parent::*)"/> ; <xsl:value-of select="local-name()"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>        
  </xsl:for-each>
</xsl:for-each>

<xsl:for-each select="Worksheettype[@name='VoorzieningenApp']">
  <xsl:for-each select="Types/Sub/*">
    <xsl:for-each select="./*">
      <xsl:value-of select="ancestor::Worksheettype/@TypeId"/> ; <xsl:value-of select="local-name(parent::*)"/> ; <xsl:value-of select="local-name()"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:for-each>
</xsl:for-each>


<xsl:for-each select="Worksheettype[@name='RisicoKapitaalApp']">
  <xsl:for-each select="Types/Sub/*">
    <xsl:for-each select="./*">
      <xsl:value-of select="ancestor::Worksheettype/@TypeId"/> ; <xsl:value-of select="local-name(parent::*)"/> ; <xsl:value-of select="local-name()"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:for-each>
</xsl:for-each>
</xsl:template>

それは問題なく動作しますが、ご覧のとおり、3 つの同一のコード ブロックがありますが、それぞれの for-each ステートメントに異なる選択パラメーターがあります。

3 つの選択パラメーターを格納できる変数を作成し、それらを単純に反復処理して、コードを 1 ブロックだけに削減できるようにしたいと考えています。

変数を作成しようとしましたが、常に失敗します...

どんな助けでも大歓迎です:)

ありがとう!

4

2 に答える 2

1

Fbo、使用している XSLT のバージョンが指定されていません。

XSLT 2.0 ソリューション

XSLT 2.0 を使用できる場合、最も簡単な解決策は XPATH のコンマ (,) 演算子を使用することです。これは次のようになります...

<xsl:for-each select="Worksheettype[@name='DubieuzeDebiteurenApp'],
                      Worksheettype[@name='VoorzieningenApp'],
                      Worksheettype[@name='RisicoKapitaalApp']">
  <xsl:for-each select="Types/Sub/*">        
    <xsl:for-each select="./*">
      ... banana banana banana etc.       
  </xsl:for-each>
</xsl:for-each>

コンマ演算子は、表示された反復順序を保持します (VoorzieningenApp の前に DubieuzeDebiteurenApp)。

条件付き XSLT 1.0 ソリューション

繰り返しの順序 (DubieuzeDebiteurenApp が VoorzieningenApp の前) を気にしない場合、または質問の順序が既にドキュメントの順序になっている場合、XSLT 1.0 での最も単純な解決策は次のようになります。

<xsl:for-each select="Worksheettype[ (@name='DubieuzeDebiteurenApp') or
                                     (@name='VoorzieningenApp')
                                     (@name='RisicoKapitaalApp')]">

... または同等に XSLT 2.0 ...

<xsl:for-each select="Worksheettype[ @name in
    ('DubieuzeDebiteurenApp','VoorzieningenApp','RisicoKapitaalApp')]">

フォールバック XSLT 1.0 ソリューション

XSLT 1.0 に行き詰まっていて、前述の特別な条件が当てはまらない場合は、名前が付けられているかどうかに関係なくテンプレートを使用し、Tim C の解決策として 3 つの xsl:apply-templates を使用してください。(最初の正しい投稿をしてくれたティムにおめでとう)。

于 2012-07-09T08:53:29.550 に答える
1

ここで名前付きテンプレートを使用し、ワークシート名をパラメーターとして渡すだけです。

<xsl:template name="Worksheettype">
   <xsl:param name="typeName" />
   <xsl:for-each select="Worksheettype[@name=$typeName]"> 
        <!-- Remaining code -->
   </xsl:for-each>
</xsl:template>

次に、次のように呼び出します

<xsl:call-template name="Worksheettype">
   <xsl:with-param name="typeName" select="'DubieuzeDebiteurenApp'" />
</xsl:call-template>

<xsl:call-template name="Worksheettype">
   <xsl:with-param name="typeName" select="'VoorzieningenApp'" />
</xsl:call-template>

<xsl:call-template name="Worksheettype">
   <xsl:with-param name="typeName" select="'RisicoKapitaalApp'" />
</xsl:call-template>

もう 1 つの方法は、テンプレート マッチングを使用することです。最初に Worksheettype に一致するテンプレートを作成します。

<xsl:template match="Worksheettype">
    <xsl:for-each select="Types/Sub/*">
        <!-- Remaining code -->
    </xsl:for-each>
</xsl:template>

次に、各属性タイプに関連するテンプレートを適用します

<xsl:apply-templates select="Worksheettype[@type='DubieuzeDebiteurenApp']" />

<xsl:apply-templates select="Worksheettype[@type='VoorzieningenApp']" />

<xsl:apply-templates select="Worksheettype[@type='RisicoKapitaalApp']" />

このアプローチはおそらく XSLT の精神に沿ったものであり、xsl:for-each を 1 つ使用する必要がなくなります。

于 2012-07-09T08:00:33.613 に答える