RE: [xsl] XSLT variables and for-each loop

Subject: RE: [xsl] XSLT variables and for-each loop
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 13 May 2005 16:31:33 +0100
> I need to create min & max variable(s)
> to be used in many templates and sub-templates
> based on certain conditions (not always).
> 
> It can't be calculated at the beginning of the file
> (depends on other variables),
> so seems like it has to be made local variable(s).

No, it can and probably should be in a global variable. Global variables can
occur anywhere in the file and can refer to other global variables defined
later or earlier. The position in the file does not determine order of
evaluation.
> 
> Since it's not easy to calculate (20-50 lines of code each)
> probably makes sense to make a template out of it.

Yes.
> 
> What I don't know is:
> 1) how to make template to return a value, something like
> [that's not XSLT
> 2.0]:
>  <xsl:variable min><call-template
> name="calculate-min"/></xsl:variable>

Just like that! (but of course <xsl:variable name="min">
> 
> 2) how to declare a global variable and then assign it much
> later in the code;

You can't do that. The declaration and initialization are one and the same
thing, and the value can't later be changed.
> 
> 3) Also, it there a way to compare a node value with a previous
> value within a for-each loop like (to find a max value of the
> nodes):
> <xsl:for-each mystruct/mystuct1>
>  <xsl:if test="position() &gt; 1  and
>    var2 &gt; var2(position()-1)">...do something...
>  </xsl:if>
> </xsl:for-each>
> Would that work ?

The best way to get min and max in XSLT 1.0 is to sort, and take the first
or last

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

> 
> 4) Can I get access to a value from another branch
> from within for-each (where var2 and var3 are "brothers")?
> 
> Imagine you have an XML tree which has the structure like:
> mystruct/myvar1[i]/myvar/var2 and
> mystruct/myvar2[i]/myvar/var3
> 
> I need to compare the values of them for the same index "i".

You probably want something like

<xsl:for-each select="myvar1"
  <xsl:variable name="p" select="position()"/>
  <xsl:if test="number(myvar/var2) &gt; number(../myvar2[$p]/myvar/var3)


Michael Kay
http://www.saxonica.com/

Current Thread