W3C home > Mailing lists > Public > public-forms@w3.org > March 2010

Referring to the context item in locally-declared functions

From: Michael Kay <mike@saxonica.com>
Date: Wed, 10 Mar 2010 09:35:57 -0000
To: "'Erik Bruchez'" <ebruchez@orbeon.com>, <public-forms@w3.org>
Cc: <w3c-xsl-wg@w3.org>
Message-ID: <131F72ADF6D54F99B0B94B6A800B2E14@Sealion>


Thanks for asking us about this.

We (XSL WG) considered the following, translated into XSLT 2.1 terms:

  <xsl:template match="section">
    <xsl:variable name="len" select="function() { string-length(.) }"/>
    <xsl:for-each select="para">
      <xsl:value-of select="$len()"/>
    </xsl:for-each>
  </xsl:template>

This is currently illegal according to the rules for inline functions in
XPath 2.1: local inline functions are not permitted to reference the context
item.

We observed that if it were permitted, there would be two perfectly
reasonable interpretations: the context item could be captured at function
declaration time as part of the function's closure (in which case the
function call returns the length of the section element), or it could be
treated as an implicit argument supplied at function invocation time (in
which case it returns the length of the para element).

The interpretation you want to apply is the first option; however, users
might expect by analogy with system functions such as name() that the
behaviour is the second option.

We think that the XPath rules currently allow a host language that has its
own syntax for defining functions to make its own decision on how this is
handled, but we feel that disallowing access to the context item is probably
the path of least confusion.

Note that both effects can easily be achieved by explicitly using variables
or parameters (respectively):

Option A:

  <xsl:template match="section">
    <xsl:variable name="dot" select="."/>
    <xsl:variable name="len" select="function() { string-length($dot) }"/>
    <xsl:for-each select="para">
      <xsl:value-of select="$len()"/>
    </xsl:for-each>
  </xsl:template>

Option B:

  <xsl:template match="section">
    <xsl:variable name="len" select="function($dot as item())
{string-length($dot) }"/>
    <xsl:for-each select="para">
      <xsl:value-of select="$len(.)"/>
    </xsl:for-each>
  </xsl:template>


Regards,

Michael Kay
for the XSL Working Group
Received on Wednesday, 10 March 2010 09:36:28 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 1 October 2013 22:06:53 UTC