¿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>
</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
Entonces, ¿cómo obtendría el valor de dos campos diferentes para usar más adelante? – Julian
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 –