FLWOR Expressions
For |
Selects a sequence of nodes |
Let |
Binds a sequence to a variable |
Where |
Filters the nodes |
Order by |
Sorts the nodes |
Return |
What to return (gets evaluated once for every node) |
Example:
for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
The For Clause
To loop a specific number of times in a for clause, you may use the to keyword.
This
for $x in (1 to 5)
return <test>{$x}</test>
Returns
<test>1</test>
<test>2</test>
<test>3</test>
<test>4</test>
<test>5</test>
To count the iteration use the at keyword
This
for $x at $i in doc("books.xml")/bookstore/book/title
return <book>{$i}. {data($x)}</book>
Returns
<book>1. Everyday Italian</book>
<book>2. Harry Potter</book>
<book>3. XQuery Kick Start</book>
<book>4. Learning XML</book>
it is also allowed with more than one expression in the for clause. Use comma to separate each in expression.
This
for $x in (10,20), $y in (100,200)
return <test>x={$x} and y={$y}</test>
Returns
<test>x=10 and y=100</test>
<test>x=10 and y=200</test>
<test>x=20 and y=100</test>
<test>x=20 and y=200</test>
|
The Let Clause
This
let $x := (1 to 5)
return <test>{$x}</test>
Returns
<test>1 2 3 4 5</test>
|
The let clause allows variable assignments and it avoids repeating the same expression many times. The let clause does not result in iteration.
The Where Clause
This
where $x/price>30 and $x/price<100
Returns Nodes only where the price is between 30 and 100 |
The where clause is used to specify one or more criteria for the result.
The order by Clause
This
for $x in doc("books.xml")/bookstore/book
order by $x/@category, $x/title
return $x/title
Returns
<title lang="en">Harry Potter</title>
<title lang="en">Everyday Italian</title
>
<title lang="en">Learning XML</title>
<title lang="en">XQuery Kick Start</title>
|
The order by clause is used to specify the sort order of the result.
The Return Clause
This
for $x in doc("books.xml")/bookstore/book
return $x/title
Returns
<title lang="en">Everyday Italian</title>
<title lang="en">Harry Potter</title>
<title lang="en">XQuery Kick Start</title>
<title lang="en">Learning XML</title>
|
The return clause specifies what is to be returned.
|
|
XQuery Basics
doc() |
doc("books.xml") |
Used to open a file |
Path Expressions |
doc("books.xml")/bookstore/book/title |
Used to navigate through elements in an XML document |
Predicates |
doc("books.xml")/bookstore/book[price<30] |
Used to limit the extracted data |
XQuery Basic Syntax Rules
XQuery is case-sensitive |
XQuery elements, attributes, and variables must be valid XML names |
An XQuery string value can be in single or double quotes |
An XQuery variable is defined with a $ followed by a name, e.g. $bookstore |
XQuery comments are delimited by (: and :) (: XQuery Comment :)
|
Path Expressions vs. FLWOR Expressions
Path Expression |
FLWOR Expression |
doc("books.xml")/bookstore/book[price>30]/title
|
for $x in doc("books.xml")/bookstore/book where $x/price>30 return $x/title
|
These expressions yield the same result.
XQuery Comparisons
General Comparisons: =, !=, <, <=, >, >= $bookstore//book/@q > 10
Returns true if any q attributes have a value greater than 10 |
Value Comparisons: eq, ne, lt, le, gt, ge bookstore//book/@q gt 10
Returns true if there is only one q attribute returned by the expression and its value is greater than 10. If more than one 1 is returned, and error occurs |
Examples of Function Calls
Example 1: In an element
<name>{upper-case($booktitle)}</name>
Example 2: In the predicate of a path expression
doc("books.xml")/bookstore/book[substring(title,1,5)='Harry']
Example 3: In a let clause
let $name := (substring($booktitle,1,4))
|
A call to a function can appear where an expression may appear.
User-Defined Functions
If you cannot find the XQuery function you need, you can write your own. User-defined functions can be defined in the query or in a separate library.
Syntax
declare function prefix:function_name($parameter as datatype)
as returnDatatype
{
...function code here...
};
Example: Declared in the Query
declare function local:minPrice($p as xs:decimal?,$d as xs:decimal?)
as xs:decimal?
{
let $disc := ($p * $d) div 100
return ($p - $disc)
};
How to call the function
<minPrice>{local:minPrice($book/price,$book/discount)}</minPrice>
|
Note:
Use the declare function keyword.
The name of the function must be prefixed.
The data type of the parameters are mostly the same as the data types defined in XML Schema.
The body of the function must be surrounded by curly braces.
XQuery Terminology
Nodes |
In XQuery there are 7 kinds: element, attribute, text, namespace, processing-instruction, comment, and document (root) |
Atomic Values |
Atomic values are nodes with no children or parent |
Items |
Items refer to nodes and atomic values |
Parent |
Each element and attribute has one parent |
Children |
Element nodes may have 0, 1, or more children. |
Siblings |
Nodes that have the same parent |
Ancestors |
A node's parent, parent's parent, etc. |
Descendants |
A node's children, children's children, etc. |
XQuery Conditional Expressions
If-Then-Else expressions are allowed in XQuery
for $x in doc("books.xml")/bookstore/book
return if ($x/@category="children")
then <child>{data($x/title)}</child>
else <adult>{data($x/title)}</adult>
|
Note: "if-then-else" syntax: parentheses around the if expression are required. else is required, but it can be just else ().
Returning HTML
This
for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
Yields
<ul>
<li><title lang="en">Everyday Italian</title></li>
<li><title lang="en">Harry Potter</title></li>
<li><title lang="en">Learning XML</title></li>
<li><title lang="en">XQuery Kick Start</title></li>
</ul>
===================================================
This
<ul>
{
for $x in doc("books.xml")/bookstore/book/title
order by $x
return <li>{data($x)}</li>
}
</ul>
Yeilds
<ul>
<li>Everyday Italian</li>
<li>Harry Potter</li>
<li>Learning XML</li>
<li>XQuery Kick Start</li>
</ul>
|
Note: To eliminate the title element and show only data inside the title element use data($x)
Adding Elements and Attributes to the Result
This
<html>
<body>
<h1>Bookstore</h1>
<ul>
{
for $x in doc("books.xml")/bookstore/book
order by $x/title
return <li>{data($x/title)}. Category: {data($x/@category)}</li>
}
</ul>
</body>
</html>
Yields
<html>
<body>
<h1>Bookstore</h1>
<ul>
<li>Everyday Italian. Category: COOKING</li>
<li>Harry Potter. Category: CHILDREN</li>
<li>Learning XML. Category: WEB</li>
<li>XQuery Kick Start. Category: WEB</li>
</ul>
</body>
</html>
=======================================
This
<html>
<body>
<h1>Bookstore</h1>
<ul>
{
for $x in doc("books.xml")/bookstore/book
order by $x/title
return <li class="{data($x/@category)}">{data($x/title)}</li>
}
</ul>
</body>
</html>
Yields
<html>
<body>
<h1>Bookstore</h1>
<ul>
<li class="COOKING">Everyday Italian</li>
<li class="CHILDREN">Harry Potter</li>
<li class="WEB">Learning XML</li>
<li class="WEB">XQuery Kick Start</li>
</ul>
</body>
</html>
|
|