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

Subject: Re: [xsl] current() and position()?
From: "David Birnbaum djbpitt@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 2 Dec 2019 04:07:49 -0000
Dear Dimitre (cc xsl-list),

Thank you for the quick response. I had misunderstood that, as you write:
"'The context position is returned by the XPath expression position().'
This has a different, narrower meaning than the definition of position() in
XPath, as XPath doesn't know about any XSLT instructions (such
as xsl:apply-templates or xsl:for-each) ... Note also, that the context
position by definition is returned by the XPath expression: position()  --
not by expression of the kind: someItem!position()." This distinction
between position() in XSLT and position() in XPath, which I had not
appreciated previously, explains why current() may continue to point to an
item selected within <xsl:for-each> even after the position of that item in
the original sequence is no longer accessible through any operation that
can be performed on current().

Sincerely,

David

On Sun, Dec 1, 2019 at 10:41 PM Dimitre Novatchev dnovatchev@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> >        <xsl:variable name="letters" as="xs:string+" select="'a', 'b',
> 'c'"/>
> >         <xsl:for-each select="$letters">
> >             <xsl:message select="position(), current() ! position()"/>
>   >       </xsl:for-each>
>
> The XPath 2.0 Specification (
> https://www.w3.org/TR/xpath20/#dt-dynamic-context ) says:
> "The position of the first item in a sequence is always 1 (one). The
> context position is always less than or equal to the context size.'
>
> The expression is:
>
>     current() ! position()
>
> Do note that the current() function returns at most one item.
>
> So, we have a sequence of one item and according to the XPath 2.0
> specification, quoted above), the position of the first item in this
> one-item-only sequence "is always 1 (one)".
>
> In XSLT (https://www.w3.org/TR/xslt20/#focus) the *context-position *is
> defined as:
>
> "[Definition: 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. When an instruction such as xsl:apply-templates
> <https://www.w3.org/TR/xslt20/#element-apply-templates> or xsl:for-each
> <https://www.w3.org/TR/xslt20/#element-for-each> is used to process a
> sequence of items, the first item in the sequence is processed with a
> context position of 1, the second item with a context position of 2, and so
> on.] The context position is returned by the XPath expression
> <https://www.w3.org/TR/xslt20/#dt-expression> position()."
>
> This has a different, narrower meaning than the definition of position()
> in XPath, as XPath doesn't know about any XSLT instructions (such as
> xsl:apply-templates
> <https://www.w3.org/TR/xslt20/#element-apply-templates> or xsl:for-each
> <https://www.w3.org/TR/xslt20/#element-for-each> ).
>
> Note also, that the context position by definition is returned by the
> XPath expression: position()  -- not by expression of the kind:
> someItem!position()
>
> If, on the other hand we have an expression like:
>
>    $Items!position()
>
> Where $Items is a sequence of more than one item, then the result of
> evaluating this is the sequence:
>
>    1 to count($Items)
>
> Here is a simple XSLT 3.0 transformation to verify this:
>
> <xsl:stylesheet version="2.0" xmlns:xsl="
> http://www.w3.org/1999/XSL/Transform";
>   xmlns:xs="http://www.w3.org/2001/XMLSchema";>
>   <xsl:output omit-xml-declaration="yes" indent="yes"/>
>
>   <xsl:variable name="vLetters" as="xs:string+" select="('a', 'b', 'c')"/>
>
>   <xsl:template match="/">
>     <xsl:sequence select="$vLetters!position()"/>
>   </xsl:template>
> </xsl:stylesheet>
>
> When this transformation is applied on any XML document (not used), the
> result is:
>
> 1 2 3
>
> Cheers,
> Dimitre
>
>
> On Sun, Dec 1, 2019 at 5:05 PM David Birnbaum djbpitt@xxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>> Dear xsl-list,
>>
>> With apologies for what I suspect is a naive question, I am confused
>> about the context position in:
>>
>>         <xsl:variable name="letters" as="xs:string+" select="'a', 'b',
>> 'c'"/>
>>         <xsl:for-each select="$letters">
>>             <xsl:message select="position(), current() ! position()"/>
>>         </xsl:for-each>
>>
>> position() returns what I expect (1, then 2, then 3), but the value of
>> current() ! position() is always 1. In this test it doesn't matter because
>> I can just use position(), but the real use case requires me to refer the
>> position of the item selected by the <xsl:for-each> at a lower depth
>> (inside a predicate on a different sequence). I can save the value of
>> position() to a variable and use it at that lower depth, so as far as
>> getting the job done there isn't a problem, but getting the job done is
>> less interesting than understanding why my expectation was wrong.
>>
>> I thought that inside an <xsl:for-each> the function current() would
>> refer to the sequence item being processed at the moment (that is, within
>> the parent <xsl:for-each>), and its position would be the context position,
>> that is, its offset into the sequence over which <xsl:for-each> was ranging
>> by means of its @select attribute. I think what I'm seeing instead is that
>> current() ! position() returns the position of the current item inside the
>> one-item sequence being processed at the moment, which is why the value is
>> always 1. Does this mean that the context position (within the sequence
>> selected by the @select attribute on <xsl:for-each>) of the item being
>> processed is not accessible once the processing is deep enough that
>> position() by itself is not longer suitable? If current() is still the
>> current context *item*, where and why does it lose contact with its
>> original context *position*?
>>
>> Best,
>>
>> David
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by
>> email)
>>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3318727> (by
> email <>)

Current Thread