where Oh where?
The where keyword serves as a means to define conditions about which data should be chosen, and serves a purpose roughly analogous to the SQL WHERE clause. In both cases, you are creating what is called a predicate cause, which is used to narrow a specific range of potential options.
For instance, suppose you want to display only those colors that contain the letter r in a table, as shown in the previous section. (Why you'd want this search criteria is a task better suited to psychoanalysts than programmers, but it's illustrative nonetheless.) Here you could use the where clause to quantify the search (see Figure 3.2):
<html> <head> <title>Summations</title> </head> <body> <h1>Summations</h1> {let $colors :=("white","red","blue","green","yellow","purple","orange","black") return <table border="1"> <tr> <th>Color</th> <th>Example</th> </tr> {for $color in $colors where contains($color,'r')return element tr { element td {$color}, element td { attribute style {'background-color:',$color}, ' ' } } } </table> } </body> </html>
The contains() function is, of course, one of the functions that XQuery and XPath2 jointly share. It returns a Boolean value if the particular node is either a string or can be automatically converted to a string, and the second expression can be found in the first.
The where predicate should generally follow either the let or for keyword (usually for) but precede the statement's return clause. It should also return either a Boolean value or something that can be converted to a Boolean value, such as an empty node-list or sequence, the value 0 or an empty string ("").
Figure 3.2 You can filter on colors that have the letter r using the where clause.The where expression does not hold quite the same level of importance in XQuery as does the analogous WHERE expression in SQL. For starters, it is possible to use XPath predicates in the for and let expressions to act as a filter for XPath (and it is more economical to do so). The previous example can be rewritten using an XPath predicate as follows:
{for $color in $colors[contains(.,'r')] return . . .
Although this code might not be as readily understandable (you have to appreciate the rule of the context operator), it works just as well. In this case, the context operator (.) performs an automatic iteration over each node in $colors to perform the calculation to determine whether r is part of the color value. In the first case, the where expression examines each $color object in turn to determine which node to pass on; in the second, the XPath predicate winnows down the set of $colors to be passed to the iterator. It's the same result in both cases, but one occurs at a different point in the cycle than the other.