RE: [xsl] About position() in xsl:for-each-group

Subject: RE: [xsl] About position() in xsl:for-each-group
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sun, 10 Feb 2008 21:50:10 -0000
> Ah! There is indeed a difference between
> 
> <xsl:for-each-group select="cities/city" group-by="@country">
>    <xsl:value-of select="position()/>
> </xsl:for-each-group>
> 
> which prints the positions of each group as determined by the 
> document order of the first item of each group, and
> 
> <xsl:for-each-group select="cities/city" group-by="@country">
>    <xsl:value-of select="./position()/>
> </xsl:for-each-group>

There are a number of constructs which establish a new current focus (in
effect, a new iteration), and thus cause the values of ., position(), and
last() to change. One of these is the "/" operator. So ./position() does not
mean the same as position().
> 
> Does this mean that, in general, an XPath expression "p" is 
> NOT equivalent to "./p"? (Philip Wadler (2001), in his paper 
> entitled "A formal semantics of patterns in XSLT" at 
> http://homepages.inf.ed.ac.uk/wadler/topics/xml.html#xsl-semantics
> wrote, about his formalisation of a fragment of XPath 1.0 
> that `It follows immediately that the patterns p/. and p and 
> ./p are all equivalent.')

Wadler's paper claimed to be formalizing the semantics of the December 1998
draft of the language then called "XSL Patterns" which later became XPath
1.0 (at that time, patterns and expressions were the same thing). As an
introduction to the use of techniques in formal semantics the paper remains
of interest, but as a source of information about XPath it is worse than
useless. 

In particular, ./position() was not legal in XPath 1.0 and therefore Wadler
did not have to consider its meaning.

> 
> Moreover, you say that "position()" (i.e., the context 
> position) is not a property of a node, but the XPath 2.0 
> standard says that "It changes whenever the context item 
> changes." 

In XPath there are two higher-order expressions (namely E1/E2 and E1[E2])
that evaluate E2 with a different focus from that of E1. In XSLT there are
several additional such expressions: 

<xsl:for-each select="E1">
  E2
</xsl:for-each>

<xsl:for-each-group select="P">
  E2
</xsl:for-each-group>

<xsl:sort select="E2"/>

In each case E2 is evaluated repeatedly, once for each item in a sequence S;
and in each case the context for evaluation of E2 is defined to include
last(), which is the size of S; position(), which ranges from 1 to the size
of S, and ".", which is the item in S whose position is position(). In the
case of <xsl:for-each-group>, S is the sequence consisting of the initial
items in each group.

Michael Kay
http://www.saxonica.com/

Current Thread