XQJ Tutorial Part III: Querying Data from XML Files or Java XML APIs



In the previous chapter, XQJ Tutorial Part II: Setting up an XQJ Session, we learned how to create a connection. Now your application is ready to do some real work — executing queries.

The XQExpression Object

In XQJ, XQExpression objects allow you to execute XQuery expressions. XQExpression objects are created in the context of an XQConnection. The example described on this page creates an XQExpression and uses it to execute an XQuery expression. Let's take a look:

...
// assume an XQConnection xqc
XQExpression xqe = xqc.createExpression();
xqe.executeQuery("doc('orders.xml')//order[id='174']");
...

The result of an XQuery evaluation is a sequence, which is modeled as an XQSequence object in XQJ. Hence, the result of the executeQuery() method is an XQSequence. In typical scenarios the code example of above will actually look like this:

...
XQExpression xqe;
XQSequence xqs;
xqe = xqc.createExpression();
xqs = xqe.executeQuery("doc('orders.xml')//order[id='174']");
// process the query results
...

You can find details about the XQSequence functionality in XQJ Tutorial Part IV: Processing Query Results.

Reusing XQExpression Objects

An XQExpression object can be reused — a different XQuery expression can be executed each time. The next example first retrieves all orders with id 174, and next all orders with id 267:

...
XQExpression xqe;
XQSequence xqs;
xqe = xqc.createExpression();
// execute a first query
xqs = xqe.executeQuery("doc('orders.xml')//order[id='174']");
// process the query results
...
// execute a second query
xqs = xqe.executeQuery("doc('orders.xml')//order[id='267']");
// process the query results
...

Prepared Queries

XQJ supports the concept of prepared queries. The underlying rationale is to “prepare” (“compile”, if you prefer) the query only once, and subsequently “execute” it several times. During the preparation phase, the query is parsed, statically validated, and an optimized execution plan is generated. This sequence of operations can be a relatively expensive; using XQPreparedExpression objects can improve performance if the same query is executed multiple times.

Using prepared queries often implies the use of external variables in your query. The application can bind different values to each of the external variables for different executions. Here is an example that shows how the previous code snippet can be modified to take advantage of an XQPreparedExpression object. Note that the XQuery expression is specified when the XQPreparedExpression object is created, not at execution time:

...
XQPreparedExpression xqp;
XQSequence xqs;
xqp = xqc.prepareExpression(
"declare variable $id as xs:string external; " +
"doc('orders.xml')//order[id=$id]");
// execute a first query and process the query results
xqp.bindString(new QName("id"),"174", null);
xqs = xqp.executeQuery();
...
// execute a second query and process the query results
xqp.bindString(new QName("id"), "267", null);
xqs = xqp.executeQuery();
...

Context Items

XQuery has a concept of context item. The context item is represented by a "dot" in your queries. The previous examples show how values can be bound to XQExpression and XQPreparedExpression objects by name. In XQuery, the context item has no name; as such, XQJ defines a constant to bind the context item: XQConstants.CONTEXT_ITEM. The next example is similar to the previous one, but it binds the DOM document to the initial context item, rather than to an external variable:

...
Document domDocument = ...;
XQExpression xqe = xqc.createExpression();
xqe.bindNode(XQConstants.CONTEXT_ITEM, domDocument, null);
XQSequence xqs = xqe.executeQuery(".//order[id='174']");
// process the query results
...

Later in this tutorial, you'll see how to bind values to external variables or the context item in greater detail.

Using Input Streams

Note that in all the above examples, the XQuery expressions are specified as Java character strings. XQJ also allows specifying an InputStream, as shown in the next example, where the query in the getorders.xquery file is executed:

...
InputStream query;
query = new FileInputStream("home/joe/getorders.xquery")
XQExpression xqe;
XQSequence xqs;
xqe = xqc.createExpression();
xqs = xqe.executeQuery(query);
// process the query results
...

Of interest here is that an XQuery can optionally DataDirect XQuery®, this is UTF-8.