XQuery Context Support
XQuery has dual "context" concepts: static context and dynamic context. XQJ provides XQStaticContext and XQDynamicContext interfaces to model them. The XQStaticContext provides methods to retrieve information defined in the XQuery static context, such as the base URI, the boundary-space policy, etc, letting applications retrieve information about the global static context. For example, the XQConnection interface extends the XQStaticContext interface.
In contrast, the XQDynamicContext interface enables applications to retrieve information about the dynamic context, and to change that information. In particular, it provides methods to bind XQuery variables, which are part of the dynamic context, with a variety of values. Both XQPreparedExpression and XQExpression extend the XQDynamicContext. The preceding example can call the
bindString() method on an XQPreparedExpression because
bindString() is actually a method exposed by the base XQDynamicContext interface.
Unlike JDBC, because the values bound to XQuery variables may not necessarily be simple scalar values, the
bindXXX() methods in XQDynamicContext can have a deferred binding mode. In deferred binding mode, the bind value may not be consumed until the XQuery processor actually accesses the variable, which enables XQJ to potentially employ a pipeline-based lazy value evaluation model.
XQuery Data Model Support
Again, an XQuery result
is an instance of the XQuery data model, which consists of sequence of XQuery items. Each item can be an atomic value or an XML node (document, element, attribute, comment, processing instruction, or text). The XQSequence interface models the XQuery data model. It contains zero or more XQItem interface objects. The XQItem interface represents an item in the XQuery data model. Developers obtain an XQItem by invoking either the
XQSequence.getItem() method or the
XQConnection.createItem() method.
While XQItem and XQSequence can represent XQuery items and sequences created independent of an XQuery result, XQResultItem and XQResultSequence (which extend XQItem and XQSequence respectively) represent XQuery items and sequences obtained as the result of an XQuery execution.
When an XQItem is an atomic value, you can convert it into the corresponding Java data type using one of the
getXXX() methods, which include
getInt(),
getString(), and so forth. When XQItem is an XML node, you can access it via existing XML node manipulation interfaces, such as DOM, SAX, or StAX. Both XQItem and XQSequence extend the XQItemAccessor interface, which defines a variety of item accessor methods. For example, the
getNode() method returns a DOM node. The
writeItemToSAX() method generates a SAX event by serializing a sequence into SAX events. The
getItemAsStream() method serializes the sequence into an XMLStreamReader event stream. Furthermore, XQJ has defined a set of standard mapping between Java data types and XQuery data types to facilitate binding standard Java types to XQuery variables.
XQuery Type System Support
XQuery has typesand interfaces to support them. The XQSequenceType and XQItemType interfaces allow users to work with XQuery type systems. XQSequenceType interface represents a sequence type defined in XQuery, whereas XQItemType represents an item type defined in XQuery. It extends XQSequenceType but restricts its occurrence indicator to exactly one. The XQItem interface contains methods to obtain information about an XQuery item type, such as its item type, its base type, the node name (if any), the note type name (if any), and any XML schema URI associated with the type.
XQJ allows for considerable implementation freedom to deal with XML schema types. Because XQJ is designed to work with a variety of XQuery engines, you can't assume any particular relationship between the XQJ implementation and the underlying XQuery engine with which it communicates. Therefore you can't assume that a particular implementation combination of XQJ and the XQuery engine share the same XML Schema repository. To ameliorate this problem, the XQJ API uses an XQMetaData method called
isUserDefinedXMLSchemaTypeSupported() to decide whether the XQJ implementation can answer questions that depend on the knowledge XML schemas. For a tightly coupled system where the XQuery engine and the XQJ implementation share the same XML schema repository,
isUserDefinedXMLSchemaTypeSupported is set to
true; for loosely coupled systems, this value is set to
false.
Working with XQMetaData
The XQMetaData interface provides users with additional information about the underlying XQJ and XQuery implementation. It has methods to query whether specific XQuery features, such as
StaticTypingFeature and
SchemaImportFeature, are supported. It also provides general information about the data source. The XQMetaData interface functions as a portable layer for XQJ users. This is similar to the DatabaseMetaData interface in JDBC.
Future Directions
As
SQL/XML becomes the standard, developers will be able to embed and execute XQuery within SQLso JDBC will eventually be enhanced with XQuery support. However, we believe that XQJ is still necessary, because not all XQuery processors that require XQJ will support SQL and SQL/XML. Furthermore, XQJ has defined a number of important interfaces (as described earlier) that model the key concepts in XQuery, as well as classical XML Java interfaces such as DOM, SAX, and StaX. These XQJ interfaces will be leveraged when JDBC eventually supports SQL/XML 2006, which allows XQuery invocation in SQL. A potential integration point is to have the JDBC XMLType support a method for creating XQuery data models using interfaces defined by XQJ.
This article provided a brief introduction to XQJ, the XQuery Java API and discussed some of the interfaces that model key concepts in XQuery. Just as JDBC was successful with relational data, we believe XQJ will become a widely used Java API for interacting with XQuery engines operating on XML data sources.