Subject: Re: [xsl] current() and position()? From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Mon, 2 Dec 2019 03:41:08 -0000 |
> <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 <>)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] current() and position()?, David Birnbaum djbpi | Thread | Re: [xsl] current() and position()?, David Birnbaum djbpi |
[xsl] current() and position()?, David Birnbaum djbpi | Date | Re: [xsl] current() and position()?, David Birnbaum djbpi |
Month |