XQuery tutorial - basics
Introduction
This is a beginners tutorial for XQuery.
Prerequisites:
Recommended reading, before this:
- XSLT Tutorial - Basics, in particular the short section on XPath.
- Basic knowledge of Xpath, see XPath tutorial - basics
- XML namespace
XQuery is an XML language for querying XML that can handle the following XML document types (both single documents or collections):
- files
- XML databases
- XML fragments in memory (e.g. DOM trees)
XQuery can express queries across all these kinds of data, whether physically stored in XML or viewed as XML via middleware. In other words, you can use it to retrieve things from files, from XML representations made from SQL databases, from native XML databases like eXist. In addition, Xquery is quite a real programming language
XQuery
- Relies on the Xpath (version 2.0) language
- Can generate new XML documents
- XQuery 1 and 2.2 does not define updating, see XQupdate (XML Query Updating)
Standards:
- http://www.w3.org/TR/xquery/ (query, stable)
- http://www.w3.org/TR/xqupdate/ (updates, recent)
- Introductory examples
Find all nodes with path //topic/title
(returns all fragments <topic><title>xxxx </title></topic> from anywhere in the tree
for $t in //topic/title return $t
Find all nodes of //topic/title in "catalog.xml"
for $t in document("catalog.xml")//topic/title return $t
same, but via HTTP
for $t in document("http://tecfa.unige.ch/proj/seed/catalog/net/catalog.xml")//topic/title return $t
Result
<title>TECFA Seed Catalog</title> <title>Introduction</title> <title>Conceptual and technical framework</title> <title>The socio-constructivist .... etc.
- Use contexts
- You need an XQuery processor
- included in some command line/library products like “saxon”
- included in XML databases.
- included in an XML editor
- included in some programming languages
Same principle as for SQL
- From the command line
- With an administration tool (Web or local)
- Trough an other web application)
- Basic XQuery
- The query expression
Recall: XQuery uses XPath elements
- position in a tree
- ex: returns all nodes <card-propvalue> under <c3mssoft-desc> ...
//c3msbrick//c3mssoft-desc//card-propvalue
- comparison
- ex: returns all nodes with this id
//c3msbrick//c3mssoft[@id="epbl"]
- functions
- ex: only returns the content of a node
//c3msbrick/title/text()
- FLWOR expressions
- FLOWR = "For-Let-Where-Order-Return"
- Similar to select-from-where-..-order-by of SQL
Overview:
- for = iteration on a list of XML nodes
- let = binding of a result to a local variable
- where = selection condition
- order = sorting
- return = expression that will be returned
For
for $variable in expression_search RETURN $variable
"for" associates to $variable each XML fragment found with the XPath (see The query expression)
Example:
for $t in //topic/title return $t
- let
- "let" assigns a value (node) to a variable
- Example without let:
for $t in document("catalog09.xml")//c3msbrick//c3mssoft-desc//card-propvalue return $t
- Same example with let
- for each node $t found, we bind $desc with a subnode.
for $t in document("catalog09.xml")//c3msbrick let $desc := $t//c3mssoft-desc//card-propvalue return $desc
- Counting, for each node $t found in the "for" loop we count the number of subnodes:
for $t in document("catalog09.xml")//c3msbrick let $n := count($t//c3mssoft) return <result> {$t/title/text()} owns {$n} bricks </result>
- where
- defines a selection condition
- Same as above, but we only return results with a least 2 <c3mssoft>
for $t in document("catalog09.xml")//c3msbrick let $n := count($t//c3mssoft) where ($n > 1) return <result> {$t/title/text()} owns {$n} bricks </result>
- order
- Can sort results
- Alphabetic sorting:
for $t in //topic/title order by $t return $t
- Alphabetic sorting
for $t in document("catalog09.xml")//c3msbrick let $n := count($t//c3mssoft) where ($n > 1) order by $n return <result> {$t/title/text()} owns {$n} bricks </result>
- Slightly more complex return clause, we also include <titles> of <c3msbricks>:
for $t in document("catalog09.xml")//c3msbrick let $brick_softs := $t//c3mssoft let $n := count($brick_softs) where ($n > 0) order by $n return <result> For {$t/title/text()} we found {$n} softwares: {$brick_softs//title} </result>
- return builds the expression to return
- Warning: Each iteration must return a fragment, i.e. a single node (and not a collection!)
Good:
for $t in document("catalog09.xml")//c3msbrick let $n := count($t//c3mssoft) return <result> {$t/title/text()} owns {$n} bricks </result>
Bad:
for $t in document("catalog09.xml")//c3msbrick let $n := count($t//c3mssoft) return $t/title/text() owns $n bricks
- Building XML fragments
- Result of an xquery usually should lead to a single node (not a list)
- Multi-fragment version (collection)
Consider the following expression
for $t in //c3msbrick/title return $t
It will return a list (a collection)
1 <title class ="- topic/title " > TECFA Seed Catalog </ title > 2 <title class ="- topic/title " > Introduction </ title > 3 <title class ="- topic/title " > Conceptual and technical framework </ title > 4 <title class ="- topic/title " > The socio-constructivist approach </ title > ....
- This sort of list is not well-formed XML, and can not be displayed in a browser for example.
- ... but this is not a problem if is dealt with by some program (e.g. a php script querying a DOM tree)
- Version single fragment
The following expression:
<result>
{ for $t in //topic/title/text()
return <titre>{$t}</titre> }
</result>
returns:
<result >
<titre > TECFA Seed Catalog </ titre >
<titre > Introduction </ titre >
<titre > Conceptual and technical framework </ titre >
<titre > The socio-constructivist approach </ titre >
....
</result>
- We replaced "title" tags by "titre" tags (just to make this a bit more complicated)
- All expression within { ...} are evaluated
- but all <tags> are copied as is ...
- For within for
- you may have loops within loops...
<result>
<title>List of C3MSBricks and associated Software</title>
{ for $t in document("catalog09.xml")//c3msbrick
let $brick_softs := $t//c3mssoft
let $n := count($brick_softs)
where ($n > 0)
order by $n descending
return
<brick> Pour {$t/title/text()} on a les {$n} modules suivants:
{ for $soft in $brick_softs
return <soft> {$soft//title/text()}</soft>
}
</brick>
}
</result>
- Each FLWOR expression is within { ... }
- The "return" clause of the outer loop includes a loop that will deal with
- $brick_softs contains a collection of $softs from which we extract titles
- We also sort the results
Result:
<result >
<title > List of C3MSBricks and associated Software </ title >
<brick > Gallery owns les 5 bricks suivants:
<soft > PhotoShare </ soft >
<soft > Photoshare combined with PageSetter </ soft >
<soft > My_eGallery </ soft >
<soft > Coppermine </ soft >
<soft > Gallery </ soft >
</ brick >
<brick > User statistics owns les 5 bricks suivants:
<soft > commArt </ soft >
<soft > pncUserPoints </ soft >
<soft > pncSimpleStats </ soft >
<soft > Statistics module </ soft >
<soft > NS-User_Points </ soft >
</ brick >
.....
</result>
Links
Software and standards
See the XQuery article.
XQuery Tutorials
- XQuery (Wikipedia article)
- XQuery - Wikibook
- Essential XQuery - The XML Query Language by Darshan Singh. (Feb 2, 2004). Good !
- XQuery Tutorial by P. Fankhauser and P. Wadler.
- An introduction to XQuery, IBM Developer works (2002, updated 2006).
- XQuery, tutorial by Anders Möller & Michael I. Schwartzbach [2003]. See also:
- Chapter 6 - Querying XML Documents with XQuery (slides) and their book An Introduction to XML and Web Technologies, ISBN 0321269667
- XQuery Tutorial from IPEDO. Quite technical.
- XQuery from the Experts: Influences on the design of XQuery Webreference Article, excerpt is from Chapter 2 of the Addison-Wesley book XQuery from the Experts. [2003]
- Michael Brundage (2004). XQuery: The XML Query Language, Portland: Book News [this is a good book]
- Comparing XSLT and XQuery by Michael Kay, Saxonica (not really a tutorial, but useful)
XQuery Web sites
- DataDirect's XQuery Developer Center (tutorials, examples, software)