Re: Making vanilla implementation of position() DTRT

Norman Walsh wrote:
> / ht@inf.ed.ac.uk (Henry S. Thompson) was heard to say:
> [...Henry's cogent arguments elided...]
> 
> Looking at the example in Henry's mail, it suddenly became clear to me
> why we can't use position() inside a for-each or viewport as we've
> been considering. The observation is so simple, I can't believe no one
> else made it before, so let me know if I'm once again overlooking the
> obvious.
> 
> Consider his example:
> 
>  <p:for-each name="myloop">
>    <p:group>
>      <p:option name="index" select="position()"/>
>       . . .
> 
> What is the context for that p:option? Depending on what we say about
> the default context for p:option, it's equivalent to one of the
> following two rewrites:
> 
>    <p:option name="index" select="position()">
>      <p:empty/>
>    </p:option>
> 
> or
> 
>    <p:option name="index" select="position()">
>      <p:pipe step="myloop" port="current"/>
>    </p:option>
> 
> In the former case, the expression is a dynamic error. In the latter
> case, position() = 1 because current doesn't produce a sequence.

This is how I suggest we define it, so that it does work in the way we'd 
expect it to:

1. We add "current document" and "current document sequence" to the 
environment. These are set as follows:

  (a) for <p:viewport> and <p:for-each>, the current document sequence 
is the sequence of documents being processed by the viewport or 
for-each, and the current document is the current document being 
processed by the viewport or for-each (which is also bound to the 
'current' port).

  (b) for <p:pipeline>, the current document and current document 
sequence are undefined.

  (c) for all other steps, the current document and current document 
sequence are the same as those of its container step. (For example, a 
group or choose doesn't change the current document or current document 
sequence.)

NOTE that neither the current document sequence nor the current document 
is the same as the default readable port: within the scope of a 
for-each, the default readable port changes between steps, but the 
current document sequence does not.

2. XPath expressions in the context of a pipeline (i.e. those that 
aren't passed as options to steps) are evaluated differently depending 
on what source they use for their context (as set by <p:xpath-context>, 
the <p:pipe> within an option or parameter and so on):

   if it's set to the current port of a for-each or viewport (either
   explicitly or implicitly [when the default readable port is the
   'current' port]), then:

      * context node = the current document
      * context position = the position of the current document in the
        current document sequence
      * context size = one of the three options we've discussed, namely
        equal to the context position, equal to MAX_INT or equal to the
        size of the current document sequence
      * variable bindings = in-scope options
      * namespace bindings = in-scope namespaces on the element whose
        attribute holds the XPath expression

   else if it's bound to a single document, then:

      * context node = that single document
      * context position = 1
      * context size = 1
      * variable bindings = in-scope options
      * namespace bindings = in-scope namespaces on the element whose
        attribute holds the XPath expression

   otherwise:

      * context node = undefined
      * context position = undefined
      * context size = undefined
      * variable bindings = in-scope options
      * namespace bindings = in-scope namespaces on the element whose
        attribute holds the XPath expression

      In this case, it's a dynamic error if the context node, position or
      size is referred to at all.

Cheers,

Jeni
-- 
Jeni Tennison
http://www.jenitennison.com

Received on Thursday, 7 June 2007 20:10:21 UTC