En XSLT, ¿cómo puedo incrementar una variable global desde un ámbito diferente?

Estoy procesando un archivo XML en el que deseo contar el número de nodos, de modo que pueda usarlo como ID a medida que escribo nuevos nodos.

Por el momento tengo una variable global llamada ‘contador’. Puedo acceder a él dentro de una plantilla, pero no he encontrado una forma de manipularlo dentro de una plantilla.

Aquí hay una versión condensada de mi archivo XSLT:

          

¿Alguna sugerencia de cómo ir desde aquí?

Otros ya han explicado cómo las variables son inmutables: que no hay sentencias de asignación en XSLT (como en el caso de los lenguajes de progtwigción puramente funcionales en general).

Tengo una alternativa a las soluciones que se han propuesto hasta ahora. Evita el paso de parámetros (que es detallado y feo en XSLT, incluso lo admitiré).

En XPath, simplemente puede contar la cantidad de elementos de

que preceden a la actual:

      

(Nota: el formato del código de espacio en blanco no aparecerá en su resultado, ya que los nodos de texto de solo espacio en blanco se eliminan automáticamente de la hoja de estilo. Por lo tanto, no se sienta obligado a poner instrucciones en la misma línea).

Una gran ventaja de este enfoque (en comparación con el uso de position() ) es que depende únicamente del nodo actual, no de la lista de nodos actual. Si cambió su procesamiento de alguna manera (por ejemplo, procesó no solo secciones sino también algún otro elemento), entonces el valor de la position() ya no correspondería necesariamente a la posición de los elementos

en su documento. Por otro lado, si usa count() como arriba, siempre corresponderá a la posición de cada elemento

. Este enfoque reduce el acoplamiento con otras partes de su código, que generalmente es algo muy bueno.

Una alternativa para count () sería usar la instrucción . Su comportamiento predeterminado numerará todos los elementos con el mismo nombre en el mismo nivel, que es lo que desea:

         

Es una compensación en verbosidad (que requiere una statement de variable adicional si aún desea utilizar la plantilla de valor de atributo llaves), pero solo ligeramente, ya que también simplifica drásticamente su expresión XPath.

Todavía hay más margen de mejora. Si bien eliminamos la dependencia de la lista de nodos actual, aún dependemos del nodo actual. Eso, en sí mismo, no es algo malo, pero no está inmediatamente claro al mirar la plantilla cuál es el nodo actual. Todo lo que sabemos es que la plantilla se llama ” section “; para estar seguro de lo que se está procesando, debemos buscar en otro lugar de nuestro código. Pero incluso eso no tiene que ser el caso.

Si alguna vez se siente impulsado a usar y juntos (como en su ejemplo), retroceda y descubra cómo usar lugar.

            

Este enfoque no solo es menos detallado ( reemplaza tanto a como a ), sino que también aclara inmediatamente cuál es el nodo actual. Todo lo que tienes que hacer es mirar el atributo de match e inmediatamente sabes que estás procesando un elemento

y que los elementos de

son lo que estás contando.

Para una explicación sucinta de cómo funcionan las reglas de plantilla (es decir, elementos que tienen un atributo de match ), consulte “Cómo funciona XSLT” .

Las variables XSLT no se pueden cambiar. Tendrás que pasar el valor de la plantilla a la plantilla.

Si está utilizando XSLT 2.0, puede tener parámetros y usar el efecto túnel para propagar la variable a las plantillas correctas.

Su plantilla se verá más o menos así:

       

También consulte el uso de generate-id () si desea crear identificadores.

Las variables en XSLT son inmutables, por lo que debe abordar el problema teniendo esto en cuenta. Puede usar position() directamente:

         

O de una manera más orientada a la plantilla:

       

las variables tienen un ámbito local y solo se leen en xslt.

Dependiendo de su procesador XSLT, puede introducir funciones con guiones en su XLST. Por ejemplo, la biblioteca XML de Microsoft admite la inclusión de javascript. Consulte http://msdn.microsoft.com/en-us/library/aa970889(VS.85).aspx para ver un ejemplo. Obviamente, esta táctica no funcionará si planea implementar / ejecutar XSLT en buscadores de clientes públicos; tiene que ser hecho por un procesador XSLT específico.

Puede usar la función de posición () para hacer lo que desee. Se vería algo como esto.

              

No lo he intentado yo mismo, pero podrías intentar pasar un parámetro a la plantilla. En su primera plantilla, establece el parámetro en count () (o current () ¿tal vez?) Dentro de la sentencia for-each y luego pasa ese valor a su plantilla de “sección”.

Aquí hay más sobre pasar parámetros a las plantillas

Use y $ RowNum como valor de incremento.

Ejemplo: ...

Esto creará clases para el enlace con los valores tile1, tile2, tile3, etc …