XQuery/Gotchas

generalised equals
= is a sequence comparison which is true if the intersection is not empty. Thus:

(1, 2, 3) = (3, 4, 5)

and 3 = (3, 4, 5)

but there are some oddities. For example = is false, as is    !=

The operator eq is used to compare values only.

Arithmetic operators
The minus sign needs space around it since $x-3 is a valid variable name which is not the same as $x - 3.

Matching brackets etc
Check carefully for matching single and double quotes, round and square brackets and curly braces. The java client will show the matching bracket, but errors are often poorly diagnosed by XQuery compilers.

Binding


The abbreviated form in which multiple binding statements can be separated by a comma:

let $x := 3 let $y := 4 let $x := "fred" Abbreviates to

let $x := 3, $y := 4, $x := "fred"

is convenient but can lead to errors when code is amended. Consider avoiding this syntax.

Conditional expression
The conditional expression must have the else part. Return the empty sequence if one alternative is not required:

if ($x = 4) then "Four" else

Sorting
'Order by' sorts numbers as text order by $c/population

To get it sorted as a number, you have to use the number function

order by number($C/population)

or cast to a number type

order by xs:integer($c/population)

or order by $c/population cast as xs:integer

XML construction
You can build XML by simply starting a tag. These tags are really XQuery expression operators. However, this puts you in a lexical scope where everything is XML and curly braces then switch back to normal XQuery (and an open tag will then switch back to XML). Escape curly braces with double braces.

Note the toggling between XQuery and XML construction modes:

let $a:= "bob" let $b:= "jane" let $ab := ($a, $b) return { for $person in $ab return {$person} }

Comments
Comments in XQuery use (: ... :) whereas comments in XML use

It is easy to use the wrong kind in the wrong context, particularly XQuery comments in constructed XML.

 (: a comment :)  makes the comment the text part of an XML element.

let
let statements are part of a FLWOR expression and can't appear alone. XQuery is a functional language and let statements are only temporary bindings of names to expressions.

let $x := 5 return $x

function result
return is not required in functions. It is part of a FLWOR statement and not a statement in itself (like let). So it is not required and not allowed if there is no for or let.

declare function local:sum($a, $b) { $a + $b }

or

declare function local:sum($a, $b) { let $c := $a + $b return $c } but not declare function local:sum($a, $b) { return $a + $b }

Rounding with double and floats
You might be surprised at that the result of the following:

is 6.30000000000001 This is because number casts the values to double and the double precision numbers round values using an algorithm that is statistically close when using many numbers but fails in specific test cases like this. This is not technically an error and other systems (Scala, ruby, python etc.) will also generate the same errors. The way around this is to not use the number function, but cast to an xs:decimal.