p:xquery (3.1) 

Invoke an XQuery query.

Summary

<p:declare-step type="p:xquery">
  <input port="source" primary="true" content-types="any" sequence="true"/>
  <output port="result" primary="true" content-types="any" sequence="true"/>
  <input port="query" primary="false" content-types="text xml" sequence="false"/>
  <option name="parameters" as="map(xs:QName,item()*)?" required="false" select="()"/>
  <option name="version" as="xs:string?" required="false" select="()"/>
</p:declare-step>

The p:xquery step applies an XQuery query to the sequence of documents provided on the source port.

Ports:

Port

Type

Primary?

Content types

Seq?

Description

source

input

true

any

true

The documents to invoke the XQuery query on, accessible using the XPath collection() function. The first document becomes the initial context item.

If no documents are provided on the source port, the initial context item is undefined and the default collection is empty.

result

output

true

any

true

The resulting document(s).

query

input

false

text xml

false

The XQuery query this step invokes. There are several ways to specify the query, see Specifying the query below.

Options:

Name

Type

Req?

Default

Description

parameters

map(xs:QName,item()*)?

false

()

A map with variable-names and corresponding values for the external variables in the query. See also the Passing parameters to a query example.

version

xs:string?

false

()

Explicitly sets the XQuery version to use. Probable values are 3.0 or 3.1.

If this option is not set, officially the XQuery version used is implementation-defined and therefore depends on the XProc processor used. However, most likely the XProc processor will use the version as indicated in the query (the xquery version statement at the top of the query).

Description

XQuery is a programming language for querying sets of XML (and other) documents. More background information can be found on its Wikipedia page. It is used in, for instance, XML databases like eXist and BaseX.

The p:xquery step invokes the XQuery query, as provided on the query port, on the document(s) appearing on the source port. The resulting document(s) appear on the result port.

Specifying the query

What appears on the query port determines the query the step invokes. XQuery queries are usually text documents (not XML), but there is a way to specify a query using XML-only called XQueryX. There are several ways to specify the query:

  • If the document on the query port is a text document, this is the query.

  • If the document on the query port is an XML document with root element <c:query> (the c namespace prefix must be bound to the namespace http://www.w3.org/ns/xproc-step), the text value of this root element is the query.

    Usually this means that the <c:query> root element consists of text contents only (a single text node). However, if there are child elements, all text nodes in the document will be concatenated.

  • If the document on the query port is an XML document with its root element in the XQueryX namespace (http://www.w3.org/2005/XQueryX), the document is treated as an XQueryX query.

    Whether XQueryX is supported is implementation defined and therefore depends on the XProc processor used.

  • In all other cases, the document on the query port is first serialized (as if written to disk), using the (optional) serialization document-property settings. The resulting text is used as the query.

Examples

Basic usage

Assume we have input documents containing <thing> elements and we want to output a list of these elements, ordered by the value of their id attribute. The following XQuery query, called sort-things.xql, does the trick:

xquery version "3.0" encoding "UTF-8";

<things-sorted count="{count(collection()//thing)}">
  {
    for $thing in collection()//thing
      order by @id
    return
      $thing
  }
</things-sorted>

The following pipeline releases this query on some input documents containing <thing> elements:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">

    <things>
      <!-- Input document 1 -->
      <thing id="123"/>
      <nested-things>
        <thing id="456"/>
      </nested-things>
    </things>

    <things>
      <!-- Input document 2 -->
      <thing id="789"/>
    </things>

  </p:input>
  <p:output port="result" sequence="true"/>

  <p:xquery>
    <p:with-input port="query" href="sort-things.xql"/>
  </p:xquery>

</p:declare-step>

Result document:

<things-sorted count="3">
   <thing id="123"/>
   <thing id="456"/>
   <thing id="789"/>
</things-sorted>

Passing parameters to a query

Let’s make the Basic usage example also usable for other elements than <thing>. The name of the element to count is passed as an external variable. The query, called sort.xql, is as follows:

xquery version "3.0" encoding "UTF-8";

declare variable $elm-name as xs:string external;

<things-sorted count="{count(collection()//*[local-name() eq $elm-name])}">
  {
    for $elm in collection()//*[local-name() eq $elm-name]
      order by @id
    return
      $elm
  }
</things-sorted>

The following pipeline releases this query on the same input documents as the Basic usage example. It again selects <thing> elements, but the (local) name of this element is now passed as an external variable:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">

  <p:input port="source" sequence="true">

    <things>
      <!-- Input document 1 -->
      <thing id="123"/>
      <nested-things>
        <thing id="456"/>
      </nested-things>
    </things>

    <things>
      <!-- Input document 2 -->
      <thing id="789"/>
    </things>

  </p:input>
  <p:output port="result" sequence="true"/>

  <p:xquery parameters="map{'elm-name': 'thing'}">
    <p:with-input port="query" href="sort.xql"/>
  </p:xquery>

</p:declare-step>

Result document:

<things-sorted count="3">
   <thing id="123"/>
   <thing id="456"/>
   <thing id="789"/>
</things-sorted>

Additional details

  • Which XQuery version(s) is/are supported is implementation-defined and therefore depends on the XProc processor used.

  • No document-properties from the source document(s) are preserved.

  • The base-uri document of each result document is determined by the query. If the query does not establish a base URI, the document will not have a base-uri document-property.

Errors raised

Error code

Description

XC0009

It is a dynamic error if the specified XQuery version is not available.

XC0101

It is a dynamic error if a document appearing on port source cannot be represented in the XDM version associated with the chosen XQuery version, e.g. when a JSON document contains a map and XDM 3.0 is used.

XC0102

It is a dynamic error if any key in option parameters is associated to a value that cannot be represented in the XDM version associated with the chosen XQuery version, e.g. with a map, an array, or a function when XDM 3.0 is used.

XC0103

It is a dynamic error if any error occurs during XQuery’s static analysis phase.

XC0104

It is a dynamic error if any error occurs during XQuery’s dynamic evaluation phase.

Reference information

This description of the p:xquery step is for XProc version: 3.1. This is a required step (an XProc 3.1 processor must support this).

The formal specification for the p:xquery step can be found here.

The p:xquery step is part of categories:

The p:xquery step is also present in version: 3.0.