2008-09-18 33 views
80

Cómo obtener un contador dentro de xsl: para cada bucle que reflejaría la cantidad de elemento actual procesado.
Por ejemplo, mi XML de origen seContador dentro de xsl: para cada bucle

<books> 
    <book> 
     <title>The Unbearable Lightness of Being </title> 
    </book> 
    <book> 
     <title>Narcissus and Goldmund</title> 
    </book> 
    <book> 
     <title>Choke</title> 
    </book> 
</books> 

Lo que quiero conseguir es:

<newBooks> 
    <newBook> 
     <countNo>1</countNo> 
     <title>The Unbearable Lightness of Being </title> 
    </newBook> 
    <newBook> 
     <countNo>2</countNo> 
     <title>Narcissus and Goldmund</title> 
    </newBook> 
    <newBook> 
     <countNo>3</countNo> 
     <title>Choke</title> 
    </newBook> 
</newBooks> 

El XSLT para modificar:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="/"> 
     <newBooks> 
      <xsl:for-each select="books/book"> 
       <newBook> 
        <countNo>???</countNo> 
        <title> 
         <xsl:value-of select="title"/> 
        </title> 
       </newBook> 
      </xsl:for-each> 
     </newBooks> 
    </xsl:template> 
</xsl:stylesheet> 

Así que la pregunta es qué poner en su sitio de ??? ¿Hay alguna palabra clave estándar o simplemente debo declarar una variable e incrementarla dentro del ciclo?

Como la cuestión es bastante largo, probablemente debe esperar una sola línea o de respuesta de una palabra :)

Respuesta

130

position(). Ej .:

<countNo><xsl:value-of select="position()" /></countNo> 
+1

que añadir una cotización de cierre "al valor del atributo –

+6

Esto es todo lo fino y elegante hasta que tenga que añadir un filtro como el XSL: si dentro de su XSL:. For-each Entonces posición() es inútil y necesita el contador adecuado. –

+2

@Mike Stavrov ¡Eso no era parte de la pregunta! No puede cubrir todas las situaciones – redsquare

5
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:template match="/"> 
     <newBooks> 
       <xsl:for-each select="books/book"> 
         <newBook> 
           <countNo><xsl:value-of select="position()"/></countNo> 
           <title> 
             <xsl:value-of select="title"/> 
           </title> 
         </newBook> 
       </xsl:for-each> 
     </newBooks> 
    </xsl:template> 
</xsl:stylesheet> 
13

Intente insertar <xsl:number format="1. "/><xsl:value-of select="."/><xsl:text> en el lugar de ???.

Tenga en cuenta el "1." - este es el formato numérico. Más información: here

+0

Gracias, eso también es una lectura interesante. Probablemente usaré ese enfoque cuando se requiera algún formato – kristof

+0

Versión XSLT 1.0: '' – jsuddsjr

5

Probar:

<xsl:value-of select="count(preceding-sibling::*) + 1" /> 

Editar - tenía un cerebro congelar allí, la posición() es más sencillo!

+1

Todavía podría ser útil, especialmente si está seleccionando según criterios distintos de position(). +1 – jsuddsjr

5

También puede ejecutar sentencias condicionales en Postion() que pueden ser realmente útiles en muchos escenarios.

por ej.

<xsl:if test="(position()) = 1"> 
    //Show header only once 
    </xsl:if> 
+1

Esto falla si tiene un filtro como xsl: sort porque entonces el primer elemento puede no ser el primero en ser procesado. –

Cuestiones relacionadas