2012-02-12 21 views
6

Estoy aprendiendo xslt y tenía una pregunta sobre cómo puedo usar la variable xslt en diff. para cada ciclo Sé que xslt no es un lenguaje de procedimiento, por lo que no se puede acceder a la variable declarada en for loop en otro ciclo. Pero, ¿hay alguna manera de que pueda declarar la variable global, luego asignar algún valor en primer para el ciclo y usar esa variable en el segundo para el ciclo?alcance variable xslt y su uso

Cualquier idea sería muy apreciada.

Gracias

Respuesta

13

¿hay alguna manera que sólo puede declarar la globa l variable luego asigne un valor de en primer lugar para el ciclo y use esa variable en el segundo para el ciclo?

La manera de asignar un valor a una xsl:variable (por supuesto esto es sólo inicialización) desde dentro de una xsl:for-each, es incluir la xsl:for-each en el cuerpo de la variable de.

Aquí es un ejemplo completo:

<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="/*"> 
    <xsl:variable name="vMax"> 
     <xsl:for-each select="num"> 
     <xsl:sort data-type="number" order="descending"/> 

     <xsl:if test="position() = 1"> 
     <xsl:value-of select="."/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 

    Values close to the maximum: 
<xsl:text/> 

     <xsl:for-each select="num"> 
     <xsl:if test="not($vMax - . > 3) "> 
     <xsl:value-of select="."/> 
     <xsl:text>&#xA;</xsl:text> 
     </xsl:if> 
     </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación en el siguiente documento XML ...

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

... primero define una variable que recibe vMax su valor del xsl:for-each contenido en su cuerpo.

Luego, la variable vMax se usa en el segundo xsl:for-each para generar todos los números que están "cerca" del máximo calculado.

La quería, resultado correcto se produce:

 Values close to the maximum: 
07 
08 
09 
10 

También es posible simular "asignar" una variable con diferentes valores mediante el uso de una forma recursiva llamada plantilla llamada y pasar el "nuevo valor" como parámetro a la plantilla llamada.

Aquí hay un ejemplo que muestra esta técnica. Aquí estamos calculando el máximo de valores, contenidos en los nodos de un conjunto de nodos. Cada vez que accedemos al siguiente nodo en el conjunto de nodos, el máximo actual se compara con este valor y, si es necesario, el nuevo máximo se convierte en el valor del siguiente nodo. Luego llamamos a la misma plantilla de forma recursiva, que pasa como el valor de la corriente máxima del nuevo máximo:

<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="/*"> 
    <xsl:call-template name="max"> 
    <xsl:with-param name="pList" select="*"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="max"> 
    <xsl:param name="pMax" select="-99999999"/> 
    <xsl:param name="pList"/> 

    <xsl:choose> 
    <xsl:when test="$pList[1]"> 
     <xsl:variable name="vnewMax" select= 
     "$pMax * ($pMax >= $pList[1]) 
     + 
     $pList[1] * not($pMax >= $pList[1]) 
     "/> 

     <xsl:call-template name="max"> 
     <xsl:with-param name="pMax" select="$vnewMax"/> 
     <xsl:with-param name="pList" select="$pList[position() > 1]"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$pMax"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

Cuando se aplica esta transformación al documento mismo XML (arriba), el, resultado correcto querido se produce :

10 
+0

Entonces, ¿cómo obtendría el valor de dos campos diferentes para usar más adelante? – Julian

+0

Simplemente defina dos variables e inicialice cada una en el "campo" correspondiente. Acerca de "más tarde" - no existe tal cosa en un lenguaje funcional. La evaluación puede ocurrir en cualquier orden y/o en paralelo –

0

xsl:for-each no es un bucle en el sentido existen for o foreach bucles en las lenguas de procedimiento por lo que cualquier pregunta hablando de bucles es difícil de entender y más difícil de responder.

Si quiere usar variables globales en XSLT puede hacerlo pero enlazará un valor a la variable donde lo declara (es decir, globalmente), no puede asignar un valor más adelante en un for-each como parezca querer hacer

0
  1. que ha escrito, 'XSL es un procedimiento lang' .. Bueno, no lo es. Es un Lenguaje declarativo ..
  2. La variable se asigna junto con su declaración, ¡las variables no cambian!
  3. Por lo general, siguen llamada recursiva para las plantillas que utilizan call-template pasar parametros a ellos .. (esto funciona como función recursiva que llama con el paso de argumentos en los lenguajes de procedimientos)
    Eso es un método para manejar el recuento de bucle y condicional etc ..

estaríamos encantados de ayudarle en caso que si uno habla de la situación exacta con XML de ejemplo, y la salida está esperando fuera de él :)

+0

sabe que es hace 3 años pero escribió * sé XSLT no es un lenguaje de procedimientos * ... – LuckyLikey

+1

@LuckyLikey, verificar el historial de edición de la cuestión, Dimitri ha corregido. Anteriormente fue "Sé que XSLT es un lenguaje de procedimiento" –

+0

tiene razón ... lo siento obtener un +1 – LuckyLikey