ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> xsl-list
xsl-list
Re: [xsl] Re: . in for
by Jeni Tennison other posts by this author
Jan 4 2002 11:28PM messages near this date
[xsl] Re: . in for | Re: [xsl] Re: . in for
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
Thread:
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Michael Kay
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Michael Kay
Dimitre Novatchev
Dimitre Novatchev
Michael Kay

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved