![]() |
Home · All Classes · Main Classes · Grouped Classes · Modules · Functions | ![]() |
While languages such as Java and C++ are largely made of statements, XQuery has expressions at its core. There is a plethora of expressions available ranging from sorting to function calls, but one of the simplest are direct node constructors, like this one:
<myElement/>
This is an XQuery query, and it also happens to be a well-formed XML document. All the usual types of nodes that can be found in an XML document can be used as expressions in XQuery, and one can go ahead and embed other expressions inside them, by using curly braces:
(: Copy the value of xml:id attribute from other.html. This is a comment by the way! :) <html xmlns="http://www.w3.org/1999/xhtml/" xml:id="{doc("other.html")/html/@xml:id}"/>
Apart from nodes, XQuery has atomic values and they are just what one would think they are: small, primitive values. Here's a run down of some of the most common:
Name | Description |
---|---|
xs:integer | A 64 bit integer |
xs:boolean | A boolean value, false or true |
xs:double | A 64 bit floating point value |
xs:string | A string where each codepoint is an XML 1.0 character(essentially Unicode) |
xs:date | A date, such as when you're born: 1984-10-15 |
xs:time | A time, such as when you show up at work: 09:00:00 |
xs:dateTime | A date followed by a time: 1984-10-15T05:00:00 |
xs:duration | A time interval such as P5Y2M10DT15H, which represents five years, two months, 10 days, and 15 hours. |
xs:base64Binary | Represents data, possibly binary data, in Base 64 encoding. |
Integers, doubles and strings can be created by using literal expressions, booleans with the functions true() or false() (just true or false would be name tests), and for the rest constructor functions must be used. Here's a query illustrating this, which evaluates to a sequence of mixed atomic values:
declare variable $date := fn:current-date(); (: This line should not be part of the example. It exists in order to make the query valid. :) fn:current-date() - $date > xs:dayTimeDuration("P365D")
Each atomic type can construct a value from a string. While doing so it validates the input string to ensure it has a proper format and if not, it issues a query error. These formats tend to be as one would guess it to be. For instance, if one passes "1.five" to xs:decimal's constructor, as opposed to "1.5" it will halt the query such that the bug can be corrected.
In the example an xs:boolean was created from an xs:integer as opposed to from a string, and that's because values doesn't have to be constructed from strings, they can be created, or converted, from a range of different types. For instance, an xs:double can be created from a xs:decimal, or a xs:boolean can be converted to an xs:string. What conversions that are possible depends on the types but they tend to be intuitive. One of the specifications has a nifty table outlining those.
Once atomic values have been constructed, via one of the methods mentioned above, or as return values from functions or by evaluating variables, one can pass them along to functions, convert them to strings and attach them as part of text nodes to nodes, or use operators between them. Let's look at the latter.
Apart from the usual arithmetic operators between numbers one would expect, they are also available between more exotic types. Have a look at this query:
It substracts two dates which returns an xs:dayTimeDuration, which it subsequently compares against another :xs:dayTimeDuration. The query finally evaluates to a single atomic value of type xs:boolean.
The available operators and between what types are summarized in a table in the main XQuery specification.
XQuery is a big language that is hard to cover in an overview. If one wants a good understanding of the subject, a good thing could be to get a book on topic, in the same manner that one has a book on C++.
Another alternative is to ask a question or two on the mailing lists qt-interest or talk on x-query.com.
Of course, the specifications is one alternative, but one has to take a deep breath before diving into those. Here are the links to (some of) them:
Often this is caused by that the names that the axis step matches, is different from nodes being matched. For instance, let's say that index.html in this query:
(: Select all paragraphs that contains examples. :) doc("index.html")/html/body/p[@class="example"]
is an XHTML document and hence it resides in the namespace http://www.w3.org/1999/xhtml/. The path won't match since they look for html and so forth, while the actual name is \{http://www.w3.org/1999/xhtml/\}html. The fix is straight forward:
declare namespace x = "http://www.w3.org/1999/xhtml/"; (: Select all paragraphs that contains examples. :) doc("index.html")/x:html/x:body/x:p[@class="example"]
Path expressions also pick up the default namespace if one is declared:
declare default element namespace "http://www.w3.org/1999/xhtml/"; <html> <body> { for $i in doc("testResult.xml")/tests/test[@status = "failure"] order by $i/@name return <p>{$i/@name}</p> } </body> </html>
In this case the nodes created by the direct element constructors will be in the XHTML namespace, but so will the path expressions. Hence they look for \{http://www.w3.org/1999/xhtml/\}tests and so forth, while testResult.xml is perhaps in a different namespace, or no namespace at all.
Due to expression precedence it might be necessary to wrap the return expression in a for clause with paranteses:
for $i in(reverse(1 to 10)), $d in xs:integer(doc("numbers.xml")/numbers/number) return ($i + $d)
Without the paranteses on the last line, the arithmetic expression would have had the whole for clause as it left operand, and since the scope of variable $d ends at the return clause, the variable reference would be out of scope.
Copyright © 2007 Trolltech | Trademarks | Qt 4.4.0-tp1 |