XQuery 3.0

From BaseX Documentation
Revision as of 19:50, 20 January 2012 by CG (talk | contribs)
Jump to navigation Jump to search

This article is part of the Query Portal. It summarizes features of the upcoming XQuery 3.0 and XPath 3.0 Recommendations that have already been implemented in BaseX.

EQNames

Template:Mark A QName can now be directly prefixed with its namespace URI, which will be enclosed in quotes and followed by a colon:

Examples:

  • "http://www.w3.org/2005/xpath-functions/math":pi() returns the number π
  • "java:java.io.FileOutputStream":new("output") creates a new Java file output stream

Namespace Constructors

Template:Mark New namespaces can now be created via computed namespace constructors.

 
element node { namespace pref { 'http://url.org/' } }

Group By

FLWOR expressions have been extended to include the group by clause, which is well-established among relational database systems. group by can be used to apply value-based partitioning to query results:

Example:

 
for $ppl in doc('xmark')//people/person  
let $ic := $ppl/profile/@income
let $income :=  if($ic < 30000) then
                   "challenge" 
                else if($ic >= 30000 and $ic < 100000) then 
                   "standard" 
                else if($ic >= 100000) then 
                   "preferred" 
                else 
                   "na"  
group by $income
order by $income
return element { $income } { count($ppl) }

This query is a rewrite of Query #20 contained in the XMark Benchmark Suite to use group by. The query partitions the customers based on their income.

Result:

<challenge>4731</challenge>
<na>12677</na>
<prefered>314</prefered>
<standard>7778</standard>

In contrast to the relational GROUP BY statement, the XQuery counterpart concatenates the values of all non-grouping variables that belong to a specific group. In the context of our example, all nodes in //people/person that belong to the "preferred" partition are concatenated in $ppl after grouping has finished. You can see this effect by changing the return statement to:

 
...
return element { $income } { $ppl }

Result:

<challenge>
  <person id="person0">
    <name>Kasidit Treweek</name>
    …
  <person id="personX">
    …
</challenge>

Try/Catch

The try/catch construct can be used to handle errors at runtime:

Example:

 try {
   1 + '2'
 } catch *($code, $desc) {
   concat('Error [', $code, ']: ', $desc)
 }

Result: Error [XPTY0004]: '+' operator: number expected, string found.

Switch

The switch statement is available in many other programming languages. It chooses one of several expressions to evaluate based on its input value.

Example:

for $fruit in ("Apple", "Pear", "Peach")
return switch ($fruit)
  case "Apple" return "red"
  case "Pear"  return "green"
  case "Peach" return "pink"
  default      return "unknown"

Result: red green pink

Function Items

Various languages features that make XQuery more functional are already completely implemented in BaseX: functions can now be dynamically invocated, inlined and passed on as arguments to other functions.

Serialization

Serialization parameters can now be defined within XQuery expressions. Parameters are placed in the query prolog and need to be specified as option declarations, using the output prefix.

Example:

declare option output:omit-xml-declaration "no";
declare option output:method "xhtml";
<html/>

Result: <?xml version="1.0" encoding="UTF-8"?><html></html>

Context Item

The context item can now be specified in the prolog of an XQuery expressions:

Example:

declare context item :=
  <xml>
    <text>Hello</text>
    <text>World</text>
  </xml>;

for $t in .//text()
return string-length($t)

Result: 5 5

Functions

BaseX supports all functions that have been added in Version 3.0 of the XQuery Functions and Operators Working Draft. The new functions are listed below:

  • math:pi(), math:sin(), and many others (see Math Module)
  • fn:analyze-string()
  • fn:available-environment-variables()
  • fn:element-with-id()
  • fn:environment-variable()
  • fn:filter()
  • fn:fold-left()
  • fn:fold-right()
  • fn:format-date()
  • fn:format-dateTime()
  • fn:format-integer()
  • fn:format-number()
  • fn:format-time()
  • fn:function-arity()
  • fn:function-name()
  • fn:generate-id()
  • fn:has-children()
  • fn:head()
  • fn:innermost()
  • fn:map()
  • fn:map-pairs()
  • fn:outermost()
  • fn:parse-xml()
  • fn:path()
  • fn:serialize()
  • fn:tail()
  • fn:unparsed-text()
  • fn:unparsed-text-available()
  • fn:unparsed-text-lines()
  • fn:uri-collection()

New signatures have been added for the following functions:

  • fn:document-uri() with 0 arguments
  • fn:string-join() with 1 argument
  • fn:node-name() with 0 arguments
  • fn:round() with 2 arguments
  • fn:data() with 0 arguments