XQJ Tutorial Part VI: Manipulating Static Context



This chapter explains how to access and manipulate the static context through the XQJ API.

XQuery defines the Static Context as follows:

    The static context of an expression is the information that is available during static analysis of the expression, prior to its evaluation.

The static context includes information like the following (refer to the XQuery specification for the complete list):

  • Default element namespace
  • Statically known namespaces
  • Context item static type
  • Default order for empty sequences
  • Boundary-space policy
  • Base uri

Initializing the Static Context

Most of the components in the static context can be initialized or augmented in the query prolog. In the following example, the boundary-space policy is explicitly specified:

declare boundary-space preserve;
<e> </e>

If a static context component is not initialized in the query prolog, an implementation default is used. Indeed, although XQuery defines default values for each of the components in the static context, as outlined in Appendix C of the XQuery specification, implementations are free to override and/or extend those defaults. In theory this means that the same query can behave in substantially different ways between two "conformant" XQuery implementations.

Setting the boundary-space Through the XQJ API

Applications often need to change the defaults for some of the static context components. If preserving boundary spaces in all queries is a requirement, applications have the option to add the boundary-space declaration to the queries, as shown above. But in many cases it is preferable to override the implementation's default through the API, so that the same settings are applied to all queries.

How can an application set boundary-space policy to preserve through the XQJ API?

...
// get a static context object with the implementation's defaults
XQStaticContext xqsc = xqc.getStaticContext();
// make sure boundary-space policy is preserve
xqsc.setBoundarySpacePolicy(XQConstants.BOUNDARY_SPACE_PRESERVE);
// make the changes effective
xqc.setStaticContext(xqsc);
...

First, you must retrieve the implementation's default values for the static context components through an XQStaticContext object. XQStaticContext defines setter and getter methods for the various static context components.

As shown in the previous example, an XQStaticContext is a value object. Changing any of the static context components doesn't have any direct effect. Only after calling setStaticContext() on the XQConnection object will the new values in the XQStaticContext become effective. Think about XQStaticContext objects as items passed by value from the XQJ driver to the application and vice-versa. Once the static context is updated, all (and only) subsequently created XQExpression and XQPreparedExpression objects will assume the new values for the static context components.

...
// the boundary-space for this first query is implementation defined,
// i.e. depends on the implementation's defaults
XQPreparedExpression xqp1 = xqc.prepareExpression("<e> </e>");
// set the boundary-space policy to preserve
XQStaticContext xqsc = xqc.getStaticContext();
xqsc.setBoundarySpacePolicy(XQConstants.BOUNDARY_SPACE_PRESERVE);
xqc.setStaticContext(xqsc);
// the boundary-space policy for this second query *is* preserve
XQPreparedExpression xqp2 = xqc.prepareExpression("<e> </e>");
...

Setting Static Context Defaults

In the previous examples, the static context is updated at the connection level, and as such all subsequently created XQExpression and XQPreparedExpression objects are affected. This is perfect if you want all your XQuery expressions to be based on the same defaults in the static context. But what if the default values need to be different for some XQExpression and XQPreparedExpression objects? The application also has the ability to specify an XQStaticContext during the creation of XQExpression and XQPreparedExpression objects:

...
// change the boundary-space policy in the static context object
// but don't apply those change at the connection level
XQStaticContext xqsc = xqc.getStaticContext();
xqsc.setBoundarySpacePolicy(XQConstants.BOUNDARY_SPACE_PRESERVE);
// create a prepared expression using the modified static context
// other expressions subsequently created are not affected
XQPreparedExpression xqp1 = xqc.prepareExpression("<e> </e>", xqsc);
...

Again, such an approach is useful if some static context components need to be changed for a specific expression, but you want to keep the default values for (most of) the other expression being executed.

Almost all static context components are accessible through XQStaticContext. Here is the list:

  • Statically known namespaces
  • Default element/type namespace
  • Default function namespace
  • Context item static type
  • Default collation
  • Construction mode
  • Ordering mode
  • Default order for empty sequences
  • Boundary-space policy
  • Copy-namespaces mode
  • Base URI

In addition, XQStaticContext includes a number of XQJ-specific properties:

  • Binding mode
  • Holdability of the result sequences
  • Scrollability of the result sequences
  • Query language
  • Query timeout

The most frequently used properties are "Binding mode" and "Scrollability," and they are discussed in other chapters of this XQJ tutorial. The query language is by default XQuery, and can be changed to XQueryX. Supporting query timeout, which sets the number of seconds an implementation will wait for a query to execute, is optional; implementations are free to ignore it.