Cameleer

XQuery component

The xquery component runs an XQuery file against the XML message body and replaces the body with the query result.

Scheme: xquery: · Crate: cameleer-xml · Cargo feature: xml · Consumer: no · Producer: yes · Apache Camel: XQuery

When to use it

  • Query and reshape XML with FLWOR expressions (for, let, where, order by, return).
  • Build a new XML document from parts of a large one, for example only the overdue invoices.
  • Extract a short text answer from an XML API response before handing it to an agent.

For a single expression inside a route step, use the XQuery language.

URI format

text
xquery:queryResource[?options]

queryResource is a file path relative to the working directory, file:path, classpath:path (read as a relative path) or ref:beanName.

Example

Select overdue invoices, sort them by amount and build a new document. The days header is bound to an external variable.

text
declare variable $in.headers.days as xs:integer external;
<overdue days="{$in.headers.days}">{
  for $i in /invoices/invoice
  where xs:integer($i/@age) gt $in.headers.days
  order by xs:decimal($i/amount) descending
  return <invoice id="{$i/@id}">{data($i/amount)}</invoice>
}</overdue>
yaml example: xquery-overdue-invoices
- route:
    id: xquery-overdue
    from:
      uri: direct:xquery-overdue
      steps:
        - setHeader:
            name: days
            constant: "30"
        - to: xquery:xq/overdue.xq
xml
<invoices>
  <invoice id="1" age="10"><amount>100</amount></invoice>
  <invoice id="2" age="45"><amount>75.5</amount></invoice>
  <invoice id="3" age="90"><amount>300</amount></invoice>
</invoices>
xml
<overdue days="30"><invoice id="3">300</invoice><invoice id="2">75.5</invoice></overdue>

Text results

resultsFormat=String concatenates the string values of the result:

text
string-join(for $p in //person order by $p/@name return string($p/@name), ', ')
yaml example: xquery-string-result
- route:
    id: xquery-names
    from:
      uri: direct:xquery-names
      steps:
        - to: xquery:xq/names.xq?resultsFormat=String
xml
<team><person name="zoe"/><person name="ali"/><person name="max"/></team>
text
ali, max, zoe

Rust DSL

rust
b.from("direct:xquery-rust")
    .to("xquery:xq/names.xq?resultsFormat=String");

Options

optiondefaultdescription
resultsFormatDOMDOM (the result serialized as XML text), String, Bytes or List. BytesSource, StringSource and DOMSource map to Bytes, String and DOM.
stripsAllWhiteSpacetrueDrop whitespace-only text nodes of the input, as Saxon does for Camel.
contentCachetrueCompile the query once.
headerName(none)Read the input document from this header instead of the body.
source(none)Input source, as in Camel (header:name, variable:name, property:name).
namespacePrefixes(none)Prefix bindings, for example p=urn:p.

Accepted and ignored (Saxon settings): configuration, configurationProperties, staticQueryContext, moduleURIResolver, parameters, properties, allowStAX, resultType, lazyStartProducer. Relative doc() URIs resolve against the query file's directory.

External variables

As in camel-saxon: declare variable $in.body external; is the body, $in.headers.NAME a header, and $NAME an exchange property, then a header, then a variable. A declared atomic type casts the value (as xs:integer); a node type (as element()) parses it as XML.

Message headers

headerdirectiondescription
any headerinAvailable as $in.headers.NAME (or $NAME) when declared external.

Run it with Docker

sh
docker run --rm -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/overdue.camel.yaml

Common questions

How do I pass a parameter to the query?

Set a header and declare it in the query: declare variable $in.headers.days as xs:integer external;.

How do I get plain text instead of XML?

Add resultsFormat=String.

Which XQuery version is supported?

XQuery 1.0 plus common 3.x conveniences such as string-join. Schema-aware features and Saxon extensions are not available.

Found a problem?

If something on this page doesn't match what Cameleer does, or you hit a bug while building with it, please help fix it, whether you are a person or a coding agent: open an issue that describes what you saw, then fork the repository, fix it, add or update a test, run cargo test --workspace, and open a pull request. CONTRIBUTING.md explains the ground rules.

Edit this page on GitHub