Subject: Re: [xsl] The output of evaluating an XSLT transform is the same regardless of the order in which output elements are evaluated. Right? From: "C. M. Sperberg-McQueen" <cmsmcq@xxxxxxxxxxxxxxxxx> Date: Thu, 15 Apr 2010 19:47:01 -0600 |
Within some limits (some of which I'll try to identify below) and modulo the fact that your terminology is kind of informal, the answer is "yes, that's true." The order of things in the result does not depend on the temporal order in which one could see expressions being evaluated by the XSLT processor if one could see into the processor: the processor is free to evaluate things in any possible order.
Some of the limitations have already been mentioned in this thread. If the value of some expression E depends on the value of some other expression F (often but not always a sub-expression), then the nature of that dependency is that the evaluation of E cannot finish before the evaluation of F.
> <xsl:text>Hello</xsl:text> > <xsl:text>World</xsl:text>
> The output will always be "HelloWorld" regardless of which > <xsl:text> element is evaluated first.
For concreteness, I'm going to assume a context like the one suggested by Syd Bauman for this:
<xsl:variable name="hw"> <xsl:text>Hello</xsl:text> <xsl:text>World</xsl:text> </xsl:variable>
There's no guarantee that the value of the variable will form part of the output of the stylesheet, so any formulation that starts "the output will always be ..." feels awkward: there won't always *be* "output" in that sense. But the string value of the variable $hw will certainly always be "HelloWorld" regardless of whether the processor evaluates the two xsl:text elements elder first, younger first, or in parallel.
One limitation needs to be mentioned, because it will be making some readers nervous along about here (if not long since): the semantics of XSLT expressions do not allow completely arbitrary reordering of evaluation events, and it is not always the case that for any two constructs A and B in an XSLT stylesheet, it's possible to evaluate them in either order, or in parallel. The difference between XSLT (and declarative languages generally) is that in XSLT the only constraints are those imposed by the logical dependencies which connect expressions. In conventional imperative languages, it is not unusual for the spec to prescribe an order for the evaluation of expressions. (The short-cut logical operators of C and other languages are an example: their prescribed meaning involves a temporal sequence for evaluating the subexpressions.)
But for the concrete example in question your statement is right: the variable $hw has as its value a sequence of two text nodes: the first has the string value "Hello" and the second the string value "World", and this will always be the case. And the reason it will always be the case is that the XSLT rule for evaluating sequence constructors is to evaluate the elements of the sequence constructor and to concatenate the resulting sequences of items. It is easy enough for a processor to represent a sequence constructor as a queue, and evaluate its elements one by one from start to end, but it's also easy to represent the constructor as a stack and evaluate the items end to start. Both give the required result, both are legal.
> Explanation: the outputs produced by each XSLT element is placed in > an in-memory "result tree."
That's a well known implementation strategy (used, for example, by the Gnome libxslt library), and can be a useful mental model of what happens.
If you leave off the "in-memory", and take "output" loosely to mean "a value visible in the output" (which is what I assume you do mean), then I think this is a fairly good way to think about the simple basic case of stylesheet processing: you're producing an output tree, and the values obtained by evaluating XSLT constructs are placed in that output tree, and at a suitable moment that result tree is written out.
But (a) nothing in the XSLT 1.0 or 2.0 specs requires that the final result tree be buffered in memory, and (b) unless you take "tree" to have a rather broad meaning, not all XSLT constructs produce trees. (Is a sequence of integers a result tree?) And (c) XSLT is carefully designed so that it's easy even for simple implementations to emit the final result tree in a streaming fashion without buffering it in memory; it is only implementations with very strong KISS principles (like libxslt) that materialize the final result tree in memory before serializing it.
> Their position in the result tree depends on the sequential order of > the outputs in the XSLT document.
True in many cases, including the $hw example above, though I would rephrase it without the "output": The relative position of values in the output depends -- often, but exception coming soon -- on the relative position of the corresponding expressions in the stylesheet.
But this is not always true: if two expressions are in different templates, and each contributes one value to a result tree, the relative position of the values in the result tree is determined by declarative rules (i.e. not by the temporal order of evaluation), but not by the textual position of the two templates.
Turn it around and restrict it to siblings, and I believe it's always true: if two sibling nodes in a stylesheet contribute one value each to a result tree, then the order of the two values in the result tree is the same as the order of the two expressions in the stylesheet.
You may make a lot of XSLT experts less nervous if you talk more about expressions and values and less about outputs, perhaps.
> occurs later in the XSLT document and so therefore it is placed > later in the result tree.
The element <xsl:text>World</xsl:text> occurs later in the sequence constructor than the element <xsl:text>Hello</text>, and therefore its string value appears later in the result tree than the string value of its older sibling.
Some contributors to the thread have suggested that one shouldn't think about things like order of execution. (I don't think anyone actually said out loud "you'll go blind if you do that", but I did get the impression that that was in the back of their minds). My experience is the contrary: learning to work with declarative systems I found it helpful to imagine as many different orders of execution as I could, not because I was interested in trying to predict the order in which a particular implementation would perform tasks, but precisely because I wanted to be clear in my mind about what properties of the sequence of events were fixed (by the language spec, or by the logical dependencies of contructs in the code) and what properties were not fixed. In particular, it can be very difficult for some programmers to break themselves of the habit of thinking of execution order as fixed. It's an important property of XSLT that the sequence constructor
<xsl:text>Hello</xsl:text> <xsl:text>World</xsl:text>
can be evaluated in document order -- it makes it much easier to write a simple (naive?) processor -- but it's an equally important property that it need not be evaluated in that order. You are right to try to get your head around that fact: don't let the warnings you have received in this thread deter you from that work. (I think some respondents thought you were trying to do something really clever with side effects, and were trying to warn you off.)
-- **************************************************************** * C. M. Sperberg-McQueen, Black Mesa Technologies LLC * http://www.blackmesatech.com * http://cmsmcq.com/mib * http://balisage.net ****************************************************************
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] The output of evaluating , Dimitre Novatchev | Thread | RE: [xsl] The output of evaluating , Costello, Roger L. |
Re: [xsl] grouping problem, Imsieke, Gerrit, le- | Date | Re: [xsl] The output of evaluating , Dimitre Novatchev |
Month |