XQuery 3.0 has been released as a working draft in December 2011. The new XQuery 3.0 specification standardizes many of the features which had been available as extension modules in eXist and other implementations for quite a while, for example: higher-order functions or try/catch.
As of February 2012, we implemented a good part of the XQuery 3.0 syntax, including:
The following sections present usage examples for those new features. If you click on the edit link, the example snippet will be loaded into eXide so you can run, edit and play around with it.
xquery version "3.0"; let $animal := "Duck" return switch ($animal) case "Cow" return "Moo" case "Cat" return "Meow" case "Duck" return "Quack" case "Dog" case "Pitbull" return "Wuff" default return "What's that odd noise?"
xquery version "3.0"; let $who := "world" return "Hello " || $who || "!"
xquery version "3.0"; let $x := "Hello" return try { $x cast as xs:integer } catch * { <error>Caught error {$err:code}: {$err:description}</error> }
xquery version "3.0"; declare namespace app="http://exist-db.org/myapp"; declare variable $app:ERROR := xs:QName("app:error"); try { error($app:ERROR, "Ooops", "any data") } catch app:error { <error>Caught error {$err:code}: {$err:description}. Data: {$err:value}.</error> }
xquery version "3.0"; declare namespace ex="http://exist-db.org/xquery/ex"; declare function ex:apply($func, $list) { for $item in $list return $func($item) }; (: Create an inline function and assign it to $f2 :) let $f2 := function($a) { upper-case($a) } return ex:apply($f2, ("Hello", "world!"))
xquery version "3.0"; declare namespace ex="http://exist-db.org/xquery/ex"; declare function ex:apply($func as function(item()) as item()*, $list) { for $item in $list return $func($item) }; (: Use function reference literal to find function at compile time :) let $fApply := ex:apply#2 return $fApply(function($a) { upper-case($a) }, ("Hello", "world!"))
xquery version "3.0"; declare namespace ex="http://exist-db.org/xquery/ex2"; declare function ex:fold-left( $f as function(item()*, item()) as item()*, $zero as item()*, $seq as item()*) as item()* { if (fn:empty($seq)) then $zero else ex:fold-left($f, $f($zero, $seq[1]), subsequence($seq, 2)) }; (: Function reference is resolved dynamically at runtime :) let $foldLeft := function-lookup(xs:QName("ex:fold-left"), 3) return $foldLeft(function($a, $b) { $a * $b}, 1, 1 to 5)
The default function library provides a number of basic functions which take function items as arguments:
map(function($a) { $a * $a }, 1 to 5)
fn:filter(function($a) {$a mod 2 = 0}, 1 to 10)
xquery version "3.0"; declare function local:apply($names as xs:string*, $f as function(xs:string) as xs:string) { for $name in $names return $f($name) }; let $string := "Hello " let $f := function($name as xs:string) { (: $string will be copied into the functions context :) $string || $name } return local:apply(("Hans", "Rudi"), $f)
When passing functions as arguments, it is often useful to be able to set certain fixed parameters when creating the function reference. XQuery 3.0 allows this using ? as an argument placeholder.
xquery version "3.0"; declare namespace ex="http://exist-db.org/xquery/ex"; declare function ex:multiply($base, $number) { $base * $number }; let $fMultiply := ex:multiply(10, ?) return map($fMultiply, 1 to 10)
View source: this page.