What Is XQuery
by Per Bothner
|
Pages: 1, 2
Path Expressions and Relationship to XPath
XQuery borrows path expressions from XPath. XQuery can be viewed as a generalization of XPath. Except for some obscure forms (mostly unusual "axis specifiers"), all XPath expressions are also XQuery expressions. For this reason the XPath specification is also being revised by the XQuery committee, with the plan that XQuery 1.0 and XPath 2.0 will be released about the same time.
The following simple example assumes an XML file
"mybook.xml" whose root element is a
<book>, containing some
<chapter> children:
let $book := document("mybook.xml")/book
return $book/chapter
The document function returns the root node of a
document. The /book expression selects the child
elements of the root that are named book, so
$book gets set to the single root element.
The $book/chapter selects the child elements of the
top-level book elements, which results in a sequence of
the second-level chapter nodes in document
order.
The next example includes a predicate:
$book//para[@class="warning"]
The double slash is a convenience syntax to select all descendants
(rather than just children) of $book, selecting only
<para> element nodes that have an attribute node
named class whose value is "warning"
One difference to note between XPath and XQuery is that XPath expressions may return a node set, whereas the same XQuery expression will return a node sequence. For compatibility these sequences will be in document order and with duplicates removed, which makes them equivalent to sets.
XSLT is very useful for expressing very simple transformations, but more complicated stylesheets (especially anything with non-trivial logic or programming) can often be written more concisely using XQuery.
Iterating Over Sequences
A for expression lets you "loop" over the elements of
a sequence:
for $x in (1 to 3) return ($x,10+$x)
The for expression first evaluates the expression
following the in. Then for each value of the resulting
sequence, the variable (in this case $x) is bound to the
value, and the return expression evaluated using that
variable binding. The value of the entire for expression is the concatenation of all values of the return
expression, in order. So the example evaluates to this 6-element
sequence: 1,11,2,12,3,13.
Here is a more useful example. Assume again that
mybook.xml is a <book> that contains
some <chapter> elements. Each
<chapter> has a <title>. The
following will create a simple page that lists the titles:
<html>{
let $book := document("mybook.xml")/book
for $ch in $book/chapter
return <h2>{$ch/title)</h2>
}</html>
The term "FLWR expressions" includes both for and
let expressions. The acronym FLWR refers to the fact
that it consists of one or more for and/or
let clauses, an optional where
clause, and a result clause. A where
clause causes the result clause to be evaluated only when
the where where expression is true.
The next example has a nested loop, allowing us to combine two
sequences: one of customer elements and the other of order elements.
We want to find the name(s) of customers who have ordered the part
whose part_id is "xx".
for $c in customers for $o in orders where $c.cust_id=$o.cust_id and $o.part_id="xx" return $c.name
This is essentially a join of two tables as commonly performed using relational databases. An important goal for XQuery is that it should be usable as a query language for XML databases. Compare the corresponding SQL statement,
select customers.name from customers, orders where customers.cust_id=orders.cust_id and orders.part_id="xx"
Functions
XQuery wouldn't be much of a programming language without user-defined functions. Such function definitions appear in the query prologue of an XQuery program. It's worth noting that function parameters and function results can be primitive values, nodes, or sequences of either.
The following is a recursive utility function. It returns all the descendant nodes of the argument, including the argument node itself. It does a depth-first traversal of the argument, returning the argument, and then looping over the argument node's children, recursively calling itself for each child.
define function descendant-or-self ($x)
{
$x,
for $y in children($x)
return descendant-or-self($y)
}
descendant-or-self(<a>X<b>Y</b></a>)
Which evaluates to this sequence of length 4:
<a>X<b>Y</b></a>; "X"; <b>Y</b>; "Y"
Sorting and Context
If you want to sort a sequence you can use a sortby
expression. To sort a sequence of books in order of author name you
can do:
$books sortby (author/name)
The sortby takes an input sequence (in this case
$books) and one or more ordering expressions.
During sorting the implementation needs to compare two values from the
input sequence to determine which comes first. It does that by
evaluating the ordering expression(s) in the context of a
value from the input sequence. So the path expression
author/name is evaluated many times, each time relative
to a different book as the context (or current) item.
Path expressions also use and set the context. In
author/name the name children that are
returned are those of the context item, which is an
author item.
Type Specification
XQuery is a strongly typed programming language. Like Java and C#, for example, it's a mix of static typing (type consistency checked at compile-time) and dynamic typing (run-time type tests). However, the types in XQuery are different from the classes familiar from object-oriented programming. Instead, it has types to match XQuery's data model, and it allows you to import types form XML Schema.
if ($child instance of element section)
then process-section($child)
else ( ) {--nothing--}
This invokes the process-section function if the value
of $child is an element whose tag name is
section. XQuery has a convenient typeswitch
shorthand for matching a value against a number of types. The
following converts a set of tag names to a different set.
define function convert($x) {
typeswitch ($x)
case element para return <p>{process-children($x)}</p>
case element emph return <em>{process-children($x)}</em>
default return process-children($x)
}
define function process-children($x) {
for $ch in children($x) return convert($ch)
}
ResourcesThe primary XQuery resource is www.w3.org/XML/Query. This has links to the draft standards, mailing lists, and implementations. The main documents are
|
There's only one XQuery book so far, mainly because there are significant loose ends in the specification: Early Adopter XQuery from Wrox. I am co-authoring (with James McGovern, Kurt Cagle, James Linn and Vaidyanathan Nagarjan) XQuery Kick Start for Sams Publishing, due to be released in 2003. There are no complete standards-conforming implementations either, but the XQuery site lists known implementations, some of which have executable demos. The only open-source implementation currently available seems to be my Qexo. (The Qexo implementation is interesting in that it compiles XQuery programs on-the-fly directly to Java bytecodes.) I recommend considering XQuery when you need a powerful and convenient tool for analyzing or generating XML.
- IE6/Win + XQuery
2006-10-27 09:08:08 frederick.c.lee - XQuery Search
2004-12-21 11:40:44 dessym79 - XQuery Search
2004-12-22 01:14:59 Per Bothner - I need to create my own Mark up language
2004-04-08 09:42:30 Senthil Jeya prakash - Please help
2004-04-08 09:40:06 Senthil Jeya prakash - Please help
2004-04-09 14:39:23 Per Bothner - Please help
2006-12-19 23:36:08 success123 - Please help
2006-12-20 13:53:20 Per Bothner - children()?
2004-03-03 19:18:14 Jun Wang - children()?
2004-03-03 19:39:54 Per Bothner - idref
2003-11-11 17:59:21 Jyothi ratna - idref
2003-11-12 11:32:24 Per Bothner - operations on xml
2003-07-19 21:43:28 Johnny Wang - operations on xml
2003-07-27 10:48:25 Per Bothner - Please Help
2003-07-09 00:59:29 Bless george - Newbie to XQuery
2003-03-23 10:17:25 Mehran Zonouzi - Newbie to XQuery
2003-03-23 13:10:35 Per Bothner - XQuery Sandbox with QEXO
2003-01-22 21:48:46 Ivelin Ivanov - Performance on large datasets?
2002-12-18 21:55:28 Larry Leeth - Another open-source implementation: Galax
2002-10-18 09:14:15 Per Bothner - Very Interesting
2002-10-18 06:31:58 Ivelin Ivanov - Future of XSLT? [was: Very Interesting]
2002-10-18 09:00:35 Per Bothner - Future of XSLT? [was: Very Interesting]
2002-10-21 23:37:24 Brandon Ibach - Future of XSLT? [was: Very Interesting]
2002-10-24 11:17:25 Per Bothner - Future of XSLT? [was: Very Interesting]
2003-01-06 17:37:12 Brandon Ibach - Future of XSLT? [was: Very Interesting]
2003-01-22 22:44:27 Per Bothner - Future of XSLT? [was: Very Interesting]
2003-02-21 12:43:32 Brandon Ibach - Future of XSLT? [was: Very Interesting]
2003-02-21 17:30:47 Per Bothner - Future of XSLT? [was: Very Interesting]
2003-03-06 06:35:10 Brandon Ibach - Future of XSLT? [was: Very Interesting]
2003-03-15 23:15:19 Per Bothner - nested loop
2002-10-17 03:30:05 Ian Young - nested loop
2002-10-18 09:07:12 Per Bothner - nested loop
2002-11-01 05:16:18 Ian Young - nested loop
2010-08-01 14:47:30 madame zora