web-dev-qa-db-fra.com

Incrémenter une valeur en XSLT

Je suis relativement nouveau dans xlst et je ne sais pas s'il existe un moyen de stocker une valeur et de la modifier plus tard, par exemple en incrémentant une variable dans une boucle.

Je suis un peu déconcerté de ne pas pouvoir changer la valeur d'un après qu'il ne soit pas logique pour moi, ce qui en fait plus une constante.

Par exemple, je veux faire quelque chose comme ceci:

<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>

Si quelqu'un peut m'éclairer pour savoir s'il existe une autre façon de procéder
Merci

28
DonutReply

XSLT est un langage fonctionnel et cela signifie entre autres que les variables en XSLT sont immuables et une fois définies, leur valeur ne peut plus être modifiée.

Voici comment le même effet peut être obtenu en 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>

lorsque cette transformation est appliquée sur le document XML suivant:

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

le résultat est:

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

Vous pouvez utiliser la fonction 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

Je l'ai rencontré moi-même il y a deux ans. Vous devez utiliser la récursivité pour cela. J'oublie la syntaxe exacte, mais ce site pourrait aider:

Astuce: boucle avec récursivité en XSLT

La stratégie fonctionne essentiellement comme suit: Remplacez la boucle for par un modèle "méthode". Demandez-lui de recevoir un paramètre i. Faites le corps de la boucle for dans la méthode du modèle. Si i > 0 Appelez à nouveau la méthode du modèle (récursivité) avec i - 1 Comme paramètre.

Pseudocode:

for i = 0 to 10:
   print i

devient:

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

Veuillez noter que l'utilisation de position() dans un xsl:for-each (Voir les autres réponses) peut être plus simple si tout ce que vous voulez faire est d'avoir un incrément variable. Utilisez le type de récursivité expliqué ici si vous voulez une boucle/condition plus compliquée.

1
Daren Thomas