Re: [xsl] Re: . in for

Subject: Re: [xsl] Re: . in for
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 4 Jan 2002 23:28:46 +0000
Dimitre,

>> I can see two drawbacks to using a simple mapping operator rather
>> than a for expression, because the context item is used rather than
>> there being explicit variable bindings for range variables:
>> 
>>  - you cannot iterate over several sequences at the same time
>>  - you cannot have right operands that use the value of the item from
>>    the left operand within a predicate
>
> Could you, please, provide concrete examples (expressions) that
> would be illegal/would not work?

Sure. The XPath 2.0 WD gives only two distinct examples of the for
expression, and neither of them would be achievable using the simple
mapping operator.

The first one has two range variables, as follows:

  for $i in (1, 2),
      $j in (3, 4)
  return ($i, $j)

which returns the sequence:

  (1, 3, 1, 4, 2, 3, 2, 4)

and is equivalent to:

  for $i in (1, 2)
  return for $j in (3, 4)
         return ($i, $j)

This iterates over two sequences - (1, 2) and (3, 4) - within the same
for expression, to create the sequence that contains pairs of possible
combinations (ish - obviously in flat sequences the 'pairedness' isn't
explicit).

The second example has two for expressions. The inner for expression
creates a sequence to iterate over using the range variable from the
outer for expression within a predicate:

  for $a in distinct-values(//author)
  return ($a,
          for $b in //book[$b/author = $a]
          return $b/title)

I don't think that you can do either of these with the operator syntax
because you lose track of what *was* the context node as you go from
one step to the next. If the outer context item was available with the
current() function, say, then you could do:

  (1, 2) -> ((3, 4) -> (current(), .))

and:

  distinct-values(//author) ->
    (//book[author = current()] -> (current(), title))

but without range variables, you can't manage these situations.

Although actually, in a good XSLT stylesheet where the book elements
were indexed by author using a 'books-by-author' key, you could do:

  distinct-values(//author)
    /key('books-by-author', .)
    /title

or, assuming that books have only one author, since neither
distinct-values() nor key() can return duplicate nodes, you would be
able to use the mapping operator to achieve the same thing:

  distinct-values(//author) -> key('books-by-author', .)
                            -> title

which demonstrates the similarity between the / operator and a mapping
operator.

Cheers,

Jeni

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


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread