Re: [xsl] Re: Re: Increment/decrement a variable in XSL

Subject: Re: [xsl] Re: Re: Increment/decrement a variable in XSL
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 5 Apr 2002 00:56:14 +0100
Dimitre wrote:
> Petr Cimprich <petr at gingerall dot cz> wrote:
>> I think that EXSLT.org's primary goal is to make extensions (more)
>> portable. The suggested solution should work with every processor
>> supporting EXSLT's funct:script. I agree that this may be mere
>> theory and I'm not sure how many processors support this extension
>> element now.
>
> While I'm not a fan of EXSL, I feel offended for them -- they never
> intended to propose extension functions for incrementing an
> xsl:variable -- or am I wrong Jeny?

Dimitre's absolutely right. Being able to bug out to a different
programming language can be really useful because they have support
for things that XPath/XSLT doesn't support (e.g. regular expressions)
or because they have access to system information that XPath doesn't
have access to (e.g. the current date and time; file listings).
func:script (and xsl:script in the XSLT 1.1 WD, on which it's based)
give a standard way of referring to implementations of extension
functions in other programming languages for these kinds of tasks.

However, it's very dangerous to use extension functions or extension
elements that have side-effects in XSLT, such as counters or
extensions that read and update databases. This is because XSLT is
designed around the basic assumption that you can evaluate the same
expression multiple times without affecting the result of that or
other expressions.

Imagine you had a simple function:

<func:script language="javascript" implements-prefix="my">
  var count = 0;
  function increment() {
    count++;
    return count;
  }
</func:script>

And that in your XSLT you had:

  <xsl:variable name="count" select="my:increment()" />
  <xsl:value-of select="$count" />
  <xsl:value-of select="$count + 1" />

As XSLT is designed, a processor is free to evaluate the expression
"my:increment()" once, five times, ten times, 100 times if it wants.
Realistically, a processor might evaluate it once (to assign the
result to $count, which is then used in the two xsl:value-of
instructions) or it might evaluate it twice (once for each of the
xsl:value-of instructions in which the $count variable is referenced)
if it thinks that storing the variable is going to be more costly than
evaluating it twice. If it did the latter, then rather than getting
"1" and "2", you'd get "1" and "3".

Equally, if you had:

  <xsl:value-of select="my:increment()" />
  <xsl:value-of select="my:increment()" />

a processor is free to evaluate the function call my:increment() as
many times as it likes. It might evaluate it twice (once for each
xsl:value-of instruction) or it might evaluate it once (detecting that
the same expression was used in both places and that therefore it can
use the same value) if it thinks that storing the value is going to be
less costly than evaluating it twice. If it does the latter, then
rather than getting "1" and "2", you'd get "1" and "1".

In other words, the assumption that nothing in XSLT produces side
effects enables XSLT processors to make all sorts of useful
optimisations. If you use an extension that does have side effects,
and your processor performs these optimisations, then you will run
into problems.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread