What is
XQuery?
XQuery was designed to query XML data.
L=let
W=where
O=order
R=result (select)
What is
FLWOR?
FLWOR
(pronounced "flowr") is an acronym for "For, Let, Where, Order
by, Return".
- 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)
How to Select Nodes From "books.xml"?
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
The doc() function is used to open the "books.xml" file:
doc("books.xml")
Path
Expressions
XQuery uses path expressions to
navigate through elements in an XML document.
The following path expression
is used to select all the title elements in the "books.xml" file:
doc("books.xml")/bookstore/book/title
(/bookstore selects the bookstore element, /book selects all the book elements under the bookstore element, and /title selects all the title elements under each book element)
<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>
Predicates
XQuery uses
predicates to limit the extracted data from XML documents.
doc("books.xml")/bookstore/book[price<30]
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
The expression
above will select all the title elements under the book elements that are under
the bookstore element that have a price element with a value that is higher
than 30.
<title lang="en">Learning XML</title>
FLWOR
expression
for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
The for clause
selects all book elements under the bookstore element into a variable called
$x.
The where clause
selects only book elements with a price element with a value greater than 30.
The order by clause
defines the sort-order. Will be sort by the title element.
The return clause
specifies what should be returned. Here it returns the title elements.
The result of the XQuery expression above will be:
<title lang="en">Learning XML</title>
<title lang="en">XQuery Kick Start</title>
In XQuery,
there are seven kinds of nodes: element, attribute, text,
namespace, processing-instruction, comment, and document (root) nodes.
Look at the following XML document:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore> (root node)
<book>
<title lang="en">Harry Potter</title> (attribute
node)
<author>J K.
Rowling</author> (element node)
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
XQuery Syntax
Some 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 :), e.g. (:
XQuery Comment :)
XQuery Conditional Expressions
1) If-Then-Else" expressions
Notes on the "if-then-else" syntax: parentheses around the if expression are
required. else is required, but it can be just else ().
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>
The result of the example above will be:
<adult>Everyday Italian</adult>
<child>Harry
Potter</child>
<adult>XQuery
Kick Start</adult>
<adult>Learning
XML</adult>
XQuery Comparisons
In XQuery there are two
ways of comparing values.
1. General comparisons: =, !=, <, <=, >, >=
2. Value comparisons: eq, ne, lt, le, gt, ge
The difference between the two comparison methods are shown below.
The following expression
returns true if any q attributes have a value greater than 10:
$bookstore//book/@q > 10
The following expression
returns true if there is only one q attribute returned by the expression, and
its value is greater than 10. If more than one q is returned, an error occurs:
$bookstore//book/@q gt 10
XQuery Selecting and Filtering
The for Clause
The for clause binds a
variable to each item returned by the in expression. The for clause results in iteration.
There can be multiple for clauses in the same FLWOR expression.
1)in
To loop a specific number of times in a for clause, you may use the in keyword:
for $x in (1
to 5)
return <test>{$x}</test>
Result:
<test>1</test>
<test>2</test>
<test>3</test>
<test>4</test>
<test>5</test>
2)at
The at keyword can be used to count the
iteration:
for $x at $i in
doc("books.xml")/bookstore/book/title
return <book> {$i}.
{data($x)} </book>
Result:
<book>1. Everyday Italian</book>
<book>2. Harry
Potter</book>
<book>3. XQuery
Kick Start</book>
<book>4. Learning
XML</book>
3)
It is also allowed with
more than one in expression in the for clause.
Use comma to separate
each in expression:
for $x in (10,20), $y in (100,200)
return <test> x={$x} and y={$y} </test>
Result:
<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>
4)
The let Clause:
The let clause allows variable assignments and it avoids
repeating the same expression many times. The let clause does not result in
iteration.
let $x := (1
to 5)
return <test>{$x}</test>
Result:
<test>1 2 3 4 5</test>
The where Clause
The where
clause is used to specify one or more criteria for the result:
where $x/price>30 and
$x/price<100
6)
The order by Clause
The order by clause is
used to specify the sort order of the result. Here we want to order the result
by category and title:
for $x in doc("books.xml")/bookstore/book
order by $x/@category, $x/title
return $x/title
Result:
<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>
7)
The return Clause
The return clause
specifies what is to be returned.
for $x in doc("books.xml")/bookstore/book
return $x/title
Result:
<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>
XQuery Functions
You can also define your own functions in XQuery.
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...
};
Notes on user-defined functions:
- 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
2) Reference XML:
XQuery functions:
declare function local:totalpricewith tax($quality as element(fruitdetails),$pice as element(fruitdetails)) as xs:decimal?
3) Reference XML:
<fruitdetails>
<fruit>
<name available=”No”>Pineapple</name>
<quantity>6</ quantity >
<price>49.99</ price >
</fruit>
<fruit>
<name available=”Yes”>Apple</name>
<quantity>24</ quantity >
<price>30.99</ price >
</fruit>
<fruit>
<name available=”No”>Banana</name>
<quantity>12</ quantity >
<price>29.99</ price >
</fruit>
</fruitdetails >
declare function local:fruitorder()
{
Let $newline := “
,”
Let $tab := “$#9;”
For $x in doc(“FruitsOrder.xml”)/fruitsdetails/fruit
Return concat(data($x/name),$tab,data($x/quantity),$tab,data($x/price) ,
$tab,$x/name/@available,$newline
};
callFunction:
Local:fruitorder()
Output:
Apple 24 30.99 yes
Banana 12 29.99 No
1) (This query going to return Title of Books costing less than 90 dollar where “ULLman” is an author.)
Where $b/@price < 90 and
$b/Authors/Author/Last_Name=”Ullman”
Return $b/Title
o Where $b/@price < 90 and
$b/Authors/Author/Last_Name=”Ullman”
2) (Titles and Author first names
of books whose title contains one of the author first names.)
Where some $fn in $b/Author/First_Name
Satisfies contains($b/Title, $fn)
Return<Book>
{$b/Title}
{$b/Authors/Author/First_Name}
</Book>
Output:
<BOOK>
<Title>Hector and Jeff’s database Hints</title>
<FirstName>Jeffrey</ FirstName >
< FirstName >Hector</ FirstName>
</BOOK>
<BOOK>
<Title>jenifer’s Economical Database Hints</title>
<FirstName> jenifer</ FirstName >
</BOOK>
3) No include only first names in book title: restricting firstname which appear into title.
For $b in doc (“Bookstore.xml”)/Bookstore/Book
Where some $fn in $b/Author/First_Name
Satisfies contains($b/Title, $fn)
Return<Book>
{$b/Title}
{for $fn in $b/Author/First_Name
Where contains($b/Title, $fn) return$fn }
</Book>
<?xml version=”1.0” encoding=”UTF-8”?>
<BOOK>
<Title>Hector and Jeff’s database Hints</title>
< FirstName >Hector</ FirstName>
</BOOK>
<BOOK>
<Title>jenifer’s Economical Database Hints</title>
<FirstName> jenifer</ FirstName >
</BOOK>
4) This query finds the average book price
<BOOK>
<Title>Hector and Jeff’s database Hints</title>
< FirstName >Hector</ FirstName>
</BOOK>
<BOOK>
<Title>jenifer’s Economical Database Hints</title>
<FirstName> jenifer</ FirstName >
</BOOK>
<Average>
{ let $plist := doc(“BookStore().xml”)/Bookstore/Book/@price
Return avg($plist) }
</ Average >
è We are going to assign our variable $plist to the result
of this expression ,(all the price
attribute in the database assign to the plist
and return average of element in that list)
NOTE: for clause is iterator and let clause is assignment
Output:
<?xml version=”1.0” encoding=”UTF-8”?>{ let $plist := doc(“BookStore().xml”)/Bookstore/Book/@price
Return avg($plist) }
</ Average >
< Average >65</ Average >
{ let $a := avg(doc(“BookStore().xml”)/Bookstore/Book/@price)
Return $a }
</ Average >
Output:
< Average >65</ Average >
5)
Let and for expression:
Find
all book whose price is below average.
for $b in doc (“Bookstore.xml”)/Bookstore/Book
where $b/@price < $a
return <Book>
{ $b/title }
<Price>{ $b/data(@price) }</Price>
</Book>
Output:
<Book>
<Title>Hector and Jeff’s database Hints</title>
<Price> 50</Price>
</Book>
<Book>
<Title>jenifer’s Economical Database Hints</title>
<Price> 25</Price>
</Book>
6) OrderBy
order by $b/@price
{ $b/title }
<Price>{ $b/data(@price) }</Price>
</Book>
Output:
<Book>
<Title>databaseSystems: The Complete book</title>
<Price>100</Price>
</Book>
<Book>
<Title>jenifer’s Economical Database Hints</title>
<Price> 25</Price>
</Book>
<Book>
<Title>Hector and Jeff’s database Hints</title>
<Price> 50</Price>
</Book>
<Book>
<Title>First cource in database system</title>
<Price> 85</Price>
</Book>
Note:
Price is string so call built in function
xs:int which convert the value in integer. So:
order by xsl:int ($b/@price )
{ $b/title }
<Price>{ $b/data(@price) }</Price>
</Book>
Output:
<Book>
<Title>jenifer’s Economical Database Hints</title>
<Price> 25</Price>
</Book>
<Book>
<Title>Hector and Jeff’s database Hints</title>
<Price> 50</Price>
</Book>
<Book>
<Title>First cource in database system</title>
<Price> 85</Price>
</Book>
<Book>
<Title>databaseSystems: The Complete book</title>
<Price>100</Price>
</Book>
7) Duplication Elimination
for $n in doc (“Bookstore.xml”)//Last_Name [// looks in depth of xml tree]
return $n
Output:
<?xml version=”1.0” encoding=”UTF-8”?>
<last_Name>Ullman</Last_name>
<last_Name>Widom</Last_name>
<last_Name>Garcia-Molina</Last_name>
<last_Name>Ullman</Last_name>
<last_Name>Widom</Last_name>
<last_Name>Ullman</Last_name>
<last_Name>Garcia-Molina</Last_name>
<last_Name>Widom</Last_name>
for $n in distinct-value(doc
(“Bookstore.xml”)//Last_Name )
return
<Last_Name> {$n}
</Last_Name>
Output:
<?xml version=”1.0” encoding=”UTF-8”?>
<last_Name>Ullman</Last_name>
<last_Name>Widom</Last_name>
<last_Name>Garcia-Molina</Last_name>
8) Every author’s first name includes “J”
for $b in doc (“Bookstore.xml”)/Bookstore/Book
where every $fn in $b/Authors/Author/First_Name
satisfies
contains($fn , “j”) [satisfy the condition first name contain letter
j]
return $b
Output:
<Book ISBN=”ISBN-0-13” Price=”85” Edition=”3rd”>
<Title>A First Cource in Database System</Title>
<Authors>
<Author>
<First_Name>Jeffrey</First_Name>
<Last_Name>Ullman</Last_Name>
</Author>
<Author>
<First_Name>Jennifer</First_Name>
<Last_Name>widom</Last_Name>
</Author>
</Authors>
</Book>
9)self-join
Call title of books which share
common author and their last name.
for $b1 in doc (“Bookstore.xml”)/Bookstore/Book
for $b2 in doc (“Bookstore.xml”)/Bookstore/Book
where
$b1/Authors/Author/Last_Name = $b2/Authors/Author/Last_Name
and
$b1/Title <
$b2/Title
Return
<BookPair>
<Title1> { data($b1/Title)
}</ Title1>
< Title2>{
data($b2/Title) }</ Title2>
</BookPair>
10) if-else:
For $x in doc(“Fruits.xml”)/fruitDetails/fruit
Return if($x/name/@available=”Yes”)
Then<li>{data($x/name)}.Available
In Store</li>
else<li>{data($x/name)}.Not
Available In Store</li>
No comments:
Post a Comment