XQuery/FLWOR Expression
Motivation
[edit | edit source]You have a sequence of items and you want to create a report that contains these items.
Method
[edit | edit source]We will use a basic XQuery FLWOR expression to iterate through each of the items in a sequence. The five parts of a FLWOR expression are:
- for - specifies what items in the sequence you want to select (optional)
- let - used to create temporary names used in the return (optional)
- where - limit items returned (optional)
- order - change the order of the results (optional)
- return - specify the structure of the data returned (required)
Lets assume we have a sample file of books that looks like this :
<books>
<book>
<title>Introduction to XQuery</title>
<description>A beginner's guide to XQuery that covers sequences and FLOWR expressions</description>
<type>softcover</type>
<sales-count>155</sales-count>
<price>19.95</price>
</book>
<book>
<title>Document Transformations with XQuery</title>
<description>How to transform complex documents like DocBook, TEI and DITA</description>
<type>hardcover</type>
<sales-count>105</sales-count>
<price>59.95</price>
</book>
<!-- ...more books here.... -->
</books>
Here is a simple example of a FLWOR expression that will return only the titles and prices of the books sorted by title:
for $book in doc("catalog.xml")/books/book
let $title := $book/title/text()
let $price := $book/price/text()
where xs:decimal($price) gt 50.00
order by $title
return
<book>
<title>{$title}</title>
<price>{$price}</price>
</book>
This XQuery FLWOR expression will return all books that have a price over $50.00. Note that we have not just one but two let statements after the for loop. We also add a where clause to restrict the results to books over $50.00. The results are sorted by the title and the result is a new sequence of book items with both the price and the title in them.
Using the "to" function to generate a range of values
[edit | edit source]You can also express a range of values from one number to another number by placing the keyword "to" between two numbers in a sequence.
The following generates a list of values from 1 to 10.
xquery version "1.0";
<list>
{for $i in (1 to 10)
return
<value>{$i}</value>
}
</list>
Using the "at" function as a counter
[edit | edit source]You can add "at $my-counter" to add a numerical counter for each item in a FLWOR loop
xquery version "1.0";
<items>
{
let $items := ("apples","pears","oranges")
for $item at $count in $items
return
<item id="{$count}">
{$item}
</item>
}
</items>
Comparing FLWOR with imperative for loops
[edit | edit source]In imperative programming languages (JavaScript, Java, .Net, Perl, PHP and Python) each loop is executed sequentially, one after another. However XQuery is a functional programming language. In a FLWOR loop, each iteration could execute in parallel and no communication is allowed between the threads. As a result, you cannot increment variables as you would in imperative languages.