Introduction to FLWOR Expressions

If you have used SQL, then you will have recognized the last example as a join between two tables - the videos table and the actors table. Join queries are not quite the same in XML, because the data is hierarchic rather than tabular, but XQuery allows you to write join queries in a similar way to the familiar SQL approach. The equivalent of the SQL SELECT expression is called the FLWOR expression, named after its five clauses: for, let, where, order by, return. Here is the last example (all videos with an actor named `Lisa', rewritten this time as a FLWOR expression.

let $doc := . 
for $v in $doc//video, 
    $a in $doc//actors/actor 
where ends-with($a, 'Lisa') 
    and $v/actorRef = $a/@id 
return $v/title  

When we run this XQuery, we get the same result as before.

Let's examine the FLWOR expression:

If you have been following very closely, you might have noticed one little XPath trick that we retained in this query: most videos will feature more than one actor (though this particular database does not attempt to catalog the bit-part players). The expression $v/actorRef therefore selects several elements. The rules for the = operator in XPath (and therefore also in XQuery) are that it compares everything on the left with everything on the right and returns true if there is at least one match. In effect, it is doing an implicit join. If you want to avoid exploiting this feature, and you want to write your query in a more classically relational form, you could express it as follows:

let $doc := . 
for $v in $doc//video, 
    $va in $v/actorRef, 
    $a in $doc//actors/actor 
where ends-with($a, 'Lisa') 
    and $va eq $a/@id 
return $v/title  

This time we used a different equality operator, eq, which follows more conventional rules than = does: it strictly compares one value on the left with one value on the right. (But like comparisons in SQL, it has special rules to handle the case where one of the values is absent.)

What about the O in FLWOR? That is there so you can get the results in sorted order. Suppose you want the videos in order of their release date. Here's the revised query:

let $doc := . 
for $v in $doc//video, 
    $a in $doc//actors/actor 
where ends-with($a, 'Lisa') 
    and $v/actorRef = $a/@id 
order by $v/year 
return $v/title 

If you are wondering why FLWOR is not really a LFWOR expression: the for and let clauses can appear in any order, and you can have any number of each. To learn more about the FLWOR expression, see Understanding FLWOR Expressions.

 
Free Stylus Studio XML Training: