XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (445 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
2.32Mb size Format: txt, pdf, ePub

It's still true that this is equivalent to a nested-loop expression:

for $c in doc(‘customers.xml’)//customer

return

   for $p in doc(‘products.xml’)//product [$c/orders/product-code = $p/code]

   return $c/line/cost

The other way to think about this, particularly if you are familiar with SQL, is as a relational join. The system isn't actually obliged to evaluate the
for
expression using nested loops (this applies whether you write it in the abbreviated form using multiple range variables separated with commas, or whether you use the expanded form shown above). Instead, the optimizer can use any of the mechanisms developed over the years in relational database technology to evaluate the join more rapidly. There's no guarantee that it will do so, so you need to use potentially expensive constructs like this with some care.

One of the differences between the open-source Saxon-B product and its commercial cousin Saxon-SA, is that Saxon-SA optimizes joins. Both products will try to move subexpressions out of a loop if they don't depend on the range variable. So the expression
doc(‘products.xml’)//product
will probably only be evaluated once, and the expression
$c/orders/product-code
will only be evaluated once for each customer. But after this, Saxon-B will compare every product code in the customer file with every product code in the product file, while Saxon-SA will create an index (in effect, doing a hash join). The bigger the data file, the more of a difference this makes.

In XSLT, you can “hand-optimize” a join by using keys: see the description of the

declaration in Chapter 6 (page 376).

Example

Expression
Description
count( for $i in 1 to 8,  $j in 1 to 8  return f:square($i
,
$j))
Assuming that
f:square(row
,
column)
returns an integer identifying the piece that occupies a square on a chessboard, or an empty sequence if the square is unoccupied, this expression returns all the pieces on the board.

Simple Mapping Expressions

You may have noticed that there are some strong similarities between
for
expressions and path expressions. The expression:

for $c in chapter return $c/section

returns exactly the same result as the path expression:

chapter/section

However, there are some significant differences between
for
expressions and path expressions:

Other books

In a Mother’s Arms by Jillian Hart, Victoria Bylin
Nanny McPhee Returns by Emma Thompson
Wake Up Dead by Roger Smith
North of Nowhere by Steve Hamilton
When I Was the Greatest by Jason Reynolds
Unbreakable by Kami Garcia
The Captain and the Enemy by Graham Greene
No Rules by McCormick, Jenna