Home Services Partners Company
XQJ Part VI - Manipulating the static context

XQJ Part VI - Manipulating the static context

August 29, 2007 0 Comments

Today's post in the XQJ series 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.

Refer to the XQuery spec for the complete list, but the static context includes for example information like,

  • default element namespace
  • statically known namespaces
  • context item static type
  • default order for empty sequences
  • boundary-space policy
  • base uri
  • etc

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

[cc lang="java"]declare boundary-space preserve; [/cc]

If a static context component is not initialized in the query prolog, an implementation default is used. Indeed, although that 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 these defaults.
In theory this means that the same query can behave substantial different between two "conformant" XQuery implementations. Talking about interoperability... Not that I know of any implementation overriding the default function namespace from 'fn' to something proprietary. If an implementation does, I guess the marketplace will decide if it was a good choice...

Anyway, back to our example. Applications often need to change the defaults for some of the static context components. If you require to preserve boundary spaces in all queries, you have the option to add the boundary-space declaration to your queries, as shown above. Or, would it be nice, if the implementation's default can be overridden through the API and become active for all queries? Well, I guess it is not a matter of one approach being better than the other, it all depends on your application design and use case.

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

[cc lang="java"]... // 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); ...[/cc]

First 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 show in the previous example an XQStaticContext is a value object. Changing any of the static context components doesn't have yet any effect. Only after calling setStaticContext() on the XQConnection object the new values in the XQStaticContext become effective. One can say that XQStaticContext objects are passed by value from the XQJ driver to the application and vice-versa.
Once the static context is being updated, all (and only) subsequently created XQExpression and XQPreparedExpression objects will assume the new values for the static context components.

[cc lang="java"]... // the boundary-space for this first query is implementation defined, // i.e. depends on the implementation's defaults XQPreparedExpression xqp1 = xqc.prepareExpression(" "); // 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(" "); ...[/cc]

In the previous examples, the static context is updated at the connection level, and as such all subsequent created XQExpression and XQPreparedExpression object are affected. This is great 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 has also the ability to specify an XQStaticContext during the creation of XQ(Prepared)Expression objects.

[cc lang="java"]... // 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(" ", xqsc); ...[/cc]

Again, such approach is useful if some static context components need to be changed for a specific expression, but want to keep the default values for most 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", which are going to be discussed in a future post in this series. The Query language is by default XQuery, and can be changed to XQueryX. Supporting query timeout is optional, implementations are free to ignore it, it sets the number of seconds an implementation will wait for a query to execute.

Looking forward to the next post? We'll discuss how XQuery types are exposed through XQJ.

digg_skin = 'compact';

Marc Van Cappellen

View all posts from Marc Van Cappellen on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments are disabled in preview mode.