Re: [xsl] current() and position()?

Subject: Re: [xsl] current() and position()?
From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 3 Dec 2019 01:19:36 -0000
I think this definition of the ! operator in the XPath 3.0 specification
explains exactly why the reported result of the evaluation is observed
https://www.w3.org/TR/xpath-30/#id-map-operator  :

"3.14 Simple map operator (!)
[34]    SimpleMapExpr
<https://www.w3.org/TR/xpath-30/#prod-xpath30-SimpleMapExpr>    ::=
PathExpr <https://www.w3.org/TR/xpath-30/#doc-xpath30-PathExpr> ("!"
PathExpr <https://www.w3.org/TR/xpath-30/#doc-xpath30-PathExpr>)*

The simple map operator "!" is used for simple mappings. Both its left-hand
side expression and its right-hand-side expression may return a mixed
sequence of nodes and non-nodes.

Each operation E1!E2 is evaluated as follows: Expression E1 is evaluated to
a sequence S. Each item in S then serves in turn to provide an inner focus
(the item as the context item, its position in S as the context position,
the length of S as the context size) for an evaluation of E2 in the dynamic
context <https://www.w3.org/TR/xpath-30/#dt-dynamic-context>. The sequences
resulting from all the evaluations of E2 are combined as follows: Every
evaluation of E2 returns a (possibly empty) sequence of items. These
sequences are concatenated and returned. If ordering mode is ordered, the
returned sequence preserves the orderings within and among the subsequences
generated by the evaluations of E2; otherwise the order of the returned
sequence is implementation-dependent."

And this is exactly what happens:  E1 is the single item returned by
current(), then it is evaluated to a sequence and each item (just one!)  in
this sequence s in turn (but just once in this case) serves as the context
item and its position in the (single-item) sequence s is the context
position. Certainly, the position of the single/only item in a sequence (of
that item only) s cannot be anything else but 1.


Cheers,

Dimitre

On Mon, Dec 2, 2019 at 3:56 PM David Birnbaum djbpitt@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> Dear Wendell and xsl-list,
>
> Thank you (also the others who have responded) for the clarification. You
> write that it "isn't about current()", but, for what it's worth, it was
> misunderstanding current() that led me to misunderstand position(). The
> spec  (20.4.1) tells me that "The current function, used within an XPath
> expression, returns the item that was the context item at the point where
> the expression was invoked from the XSLT stylesheet", continuing  (5.3.3.1)
> that "The context position is the position of the context item within the
> sequence of items currently being processed. It changes whenever the
> context item changes." I had (mis) read that to suggest that as long as
> current() referred to the same current context item, the position()
> function would refer to its original context position. That assumption was
> wrong for several reasons (e.g., I had glossed over "within the sequence of
> items currently being processed", and that had changed; XSLT position()
> isn't the same as the XPath position() function; "the 'outer' context
> position is not retrievable accessible within the 'inner' expression"),
> which are clearer now thanks to the helpful responses on the list.
>
> Best,
>
> David
>
> On Mon, Dec 2, 2019 at 11:53 AM Piez, Wendell A. (Fed)
> wendell.piez@xxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>> Dear David and XSL-List,
>>
>>
>>
>> Mike points out this isnbt about current(): it is a red herring.
>> Nonetheless it might help to keep in mind that while position() is an
XPath
>> expression, current() is not. It is defined only by XSLT.
>>
>>
>>
>> This is because its entire purpose is to refer from inside an XPath
>> expression b that is, from a processing context that has changed from
the
>> context at the start of the path b back out to the calling context.
XPath
>> without XSLT has no such context (by definition, it is provided), so it
>> does not define this function. Other languages embedding XPath offer other
>> ways of dealing with this issue. Mostly this is by providing for variable
>> bindings to be made outside the path, permitting us to reference back out
>> to some context that way. Or simply by not supporting relative XPaths from
>> arbitrary locations, so the calling context is always the document root.
>>
>>
>>
>> Indeed, since we can bind variables in XSLT, as in XQuery, we donbt
>> (mostly) need current() in XSLT either. Most always we could rewrite it
>> (apologies for smart keyboard making dumb syntax errors):
>>
>>
>>
>> <xsl:variable name="letters" as="xs:string+" select="'a', 'b', 'c'"/>
>> <xsl:for-each select="$letters">
>>
>>     <xsl:variable name=bcurrentb select=b.b/>
>>     <xsl:message select="position(), $current ! position()"/>
>> </xsl:for-each>
>>
>>
>>
>> This might suggest why the expression bcurrent() ! position()b behaves
>> the way it does. It is the same as bfor $c in (.) return position()b.
>>
>>
>>
>> So position() is not different in XPath from XSLT. The difference is only
>> where the processing context is defined, which includes position along
with
>> a context node (or item as here), context size (returned by last()) and
>> variable bindings in scope. Where the XPath is called, this context b it
>> can be thought of as a set of properties used to initialize the XPath
>> evaluation b is defined by the calling context in the XSLT. But deeper
>> inside an XPath is a different matter, since each step provides context(s)
>> for the next one (changes focus). The difference is not how position()
>> works but whose position within which sequence is being asked for.
>>
>>
>>
>> Cheers, Wendell
>>
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3318727> (by
>> email)
>>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by
> email <>)

Current Thread