Subject: CORRECTION! (was Re: Assignment no, dynamic scoping si (was: Re: RE: Wishes for XSL revisions ...)
From: "Evan Lenz" <elenz@xxxxxxxxxxx>
Date: Wed, 2 Jan 2002 14:12:24 -0800
|
Doh! My general statement was correct, but my example was wrong. So,
Wendell, sorry to mislead you, but your example in fact was wrong too!
I wrote:
> Unless a predicate is bound (without intervening parentheses) to
> a node test, it is always evaluated with respect to a "forward"
> axis (the XPath spec arbitrarily chooses the child axis).
So far, so good.
> ancestor-or-self::*[@source][last()]
>
> Your example features both kinds of predicates.
Oops. No, *both* predicates in the above example are tightly bound to the
node test (and thus the reverse axis), because the Step production is as
follows:
[4] Step ::= AxisSpecifier NodeTest Predicate*
| AbbreviatedStep
where the Step itself may have more than one predicate. So [last()] will
select the last node in *reverse* document order (or first in document
order), not the other way around! To get the intended result (getting the
"closest" ancestor), you would either write:
ancestor-or-self::*[@source][1]
or
(ancestor-or-self::*[@source])[last()]
In this second example, the [last()] predicate is no longer tightly bound to
the node test as part of the Step production; the parentheses render it as a
predicate of the second kind--as part of the FilterExpr production:
[20] FilterExpr ::= PrimaryExpr
| FilterExpr Predicate
And thus [last()] is applied to the result of the expression to the left
with respect to document order, selecting the last node in document order.
Multiple predicates in a reverse step with the last being positional--that
has got to rank pretty highly on the confuse-the-experts list of XPath
expressions.
Evan
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|