web-dev-qa-db-ja.com

XSLTで値を増やす

私はxlstを初めて使用し、値を保存して後で変更する方法があるかどうか、たとえばループ内の変数をインクリメントする方法について混乱しています。

Aの値が設定されても意味をなさないので、aの値を変更できないことに少し困惑します。

たとえば、私はこのようなことをしたい:

<xsl:variable name="i" select="0" />
<xsl:for-each select="data/posts/entry">
    <xsl:variable name="i" select="$i + 1" />
    <!-- DO SOMETHING -->
</xsl:for-each>

誰かがこれを行う別の方法があるかどうかについて私に啓発できるなら
ありがとう

28
DonutReply

XSLTは関数型言語ですこれは、変数XSLTでは不変であることを意味し、一度定義されると値を変更できません。

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="/">
   <posts>
    <xsl:for-each select="data/posts/entry">
        <xsl:variable name="i" select="position()" />
        <xsl:copy>
         <xsl:value-of select="concat('$i = ', $i)"/>
        </xsl:copy>
    </xsl:for-each>
   </posts>
 </xsl:template>
</xsl:stylesheet>

この変換が次のXMLドキュメントに適用される場合

<data>
 <posts>
  <entry/>
  <entry/>
  <entry/>
  <entry/>
  <entry/>
 </posts>
</data>

結果は

<posts>
    <entry>$i = 1</entry>
    <entry>$i = 2</entry>
    <entry>$i = 3</entry>
    <entry>$i = 4</entry>
    <entry>$i = 5</entry>
</posts>
30

position()関数を使用できます:

<xsl:for-each select="data/posts/entry">
  <xsl:text>
    Postion: '
  </xsl:text>
  <xsl:value-of select = "position()" />
  <xsl:text>
    '
  </xsl:text>
  <!-- DO SOMETHING -->
</xsl:for-each>
7
JohnB

私は2年前に自分自身に出くわしました。これには再帰を使用する必要があります。私は正確な構文を忘れていますが、このサイトは役に立つかもしれません:

ヒント:XSLTで再帰を伴うループ

戦略は基本的に次のように機能します。forループをテンプレートの「メソッド」に置き換えます。パラメーターiを受信します。テンプレートメソッドでforループの本体を実行します。 _i > 0_がパラメータとして_i - 1_を使用してテンプレートメソッドを再度呼び出します(再帰)。

擬似コード:

_for i = 0 to 10:
   print i
_

になる:

_def printer(i):
   print i
   if i < 10:
      printer(i + 1)
printer(0)
_

_xsl:for-each_(他の回答を参照)でposition()を使用する方が簡単な場合があることに注意してください。より複雑なループ/条件が必要な場合は、ここで説明する種類の再帰を使用してください。

1
Daren Thomas