Streaming in XQuery

The XQuery specification says nothing on the subject of streamed evaluation; it is left entirely to implementations. Saxon-EE supports streaming of XQuery for simple queries, using rules similar to those that apply to XSLT.

Simple queries can be streamed by specifying -stream:on on the Saxon-EE command line. There is no need to specify anything in the query itself; however, the copy-of() and snapshot() functions (defined in the XSLT 3.0 specification) may be used if streaming is not otherwise possible.

When running a query using the s9api interface, streaming must be requested both when compiling the query (XQueryCompiler.setStreaming(true)), and when executing it (XQueryEvaluator.runStreamed(Source, Destination)).

The query should access the streamed input document via the context item, not via the doc() or collection() function, nor using external variables. The source document should be supplied in the form of a SAXSource or StreamSource object.

If the query is not streamable, this will be reported as a compile-time error.

The conditions for streamability are essentially the same as the rules for the body of the xsl:source-document instruction when streamed processing is requested using the attribute streamable="yes", as in the XSLT 3.0 specification. For example:

  1. Path expressions must use downward selection only.

  2. Predicates must be motionless, which means they can reference attributes but not child elements of the node being filtered.

  3. No construct may make two downward selections. For example, the expression price - discount fails because both operands use the child axis to select downwards. If necessary, use copy-of() to copy a subtree, after which arbitrary selections within the copied subtree become possible.

  4. A streamed node may not be bound to a variable. This rules out many uses of FLWOR expressions.

  5. A streamed node must not be passed as an argument to a function call, other than built-in function calls.

  6. Global variables in the query must not reference the context item.

As with XSLT, these restrictions can often be overcome by using the copy-of() or snapshot() functions, which Saxon makes available in XQuery as well as XSLT.