2010-07-27 30 views
24

Soy bastante nuevo en xlst y estoy confundido sobre si hay alguna forma de almacenar un valor y cambiarlo más tarde, por ejemplo, incrementar una variable en un bucle.Incremente un valor en XSLT

Estoy un poco desconcertado por no ser capaz de cambiar el valor de una vez que está configurado no tiene sentido para mí, por lo que es más una constante.

Por ejemplo, yo quiero hacer algo como esto:

<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 alguien me puede iluminar sobre si existe una forma alternativa de hacer esto
Gracias

+0

Gracias Dimitre, no me di cuenta de que las variables podrían reutilizarse en un bucle for-each.Mi problema era en realidad mucho más complicado que el ejemplo que publiqué y encontré una solución usando la recursión, sin embargo buscaré una solución más elegante usando su sugerencia – DonutReply

+1

@Oliver Mientras que la recursividad es algo universal, hay formas de reemplazar la recursión con iteración. Esto resulta en aplicaciones xslt optimizadas, tanto para el tiempo como para el espacio. –

Respuesta

28

XSLT es un lenguaje funcional y entre otras cosas, esto significa que las variables en XSLT son inmutable y onc e se han definido que su valor no se puede cambiar.

Aquí es cómo el mismo efecto se puede lograr 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> 

cuando se aplica esta transformación en el siguiente documento XML:

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

el resultado es :

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

me encontré con eso mismo dos años hace. Necesitas hacer recursión para esto. Me olvido de la sintaxis exacta, pero este sitio podría ayudar:

Tip: Loop with recursion in XSLT

La estrategia funciona básicamente de la siguiente manera: sustituir for bucle con una plantilla de "método". Haz que reciba un parámetro i. Haz el cuerpo del lazo for en el método de la plantilla. Si i > 0 llama de nuevo al método de plantilla (recurrencia) con i - 1 como parámetro.

Pseudocódigo:

for i = 0 to 10: 
    print i 

se convierte en:

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

Tenga en cuenta que el uso de position() en un xsl:for-each (ver otras respuestas) puede ser más simple si todo lo que quiere hacer es tener un incremento variable. Use el tipo de recursión que se explica aquí si desea un bucle/condición más complicada.

5

Usted puede utilizar la función 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>
Cuestiones relacionadas