Is there a way that I can simply declare a global variable and then assign some value in the first for the loop and use this variable in the second for the loop?
The way to assign xsl:variable
(of course, this is just initialization) from within xsl:for-each
is to include xsl:for-each
in the body of the variable .
Here is a complete example:
<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>
When this conversion is applied to the following XML document ...
<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>
... it first defines the vMax
variable, which gets its value from xsl:for-each
contained in its body.
Then the vMax
variable vMax
used in the second xsl:for-each
to output all numbers that are "close" to the calculated maximum maximum.
The obtained, correct result is obtained :
Values close to the maximum: 07 08 09 10
You can also model the "assignment" of a variable with different values using a recursively named named template and pass the "new value" as a parameter to the called template .
Here is an example showing this technique. Here we calculate the maximum values contained in the nodes of a node -set. Each time we access the next node in node-set, the current maximum is compared with this value, and if necessary, the new maximum becomes the value of the next node. Then we call the same pattern recursively, passing the new maximum as the value of the current maximum:
<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>
When this conversion is applied to the same XML document (above), the desired, correct result is obtained :
10