XQJ Part III - Executing queries

XQJ Part III - Executing queries

August 16, 2007 0 Comments

In XQJ Part II we explained how to create a connection. Now your application is ready to do some real work, executing queries.

In XQJ an XQExpression objects allows you to execute an XQuery expression. Such XQExpression object is created in the context of an XQConnection. The next example creates an XQExpression and subsequently uses it to execute an XQuery expression,[cc lang="java"]... // assume an XQConnection xqc XQExpression xqe = xqc.createExpression(); xqe.executeQuery("doc('orders.xml')//order[id='174']"); ...[/cc]

The result of a query 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 look actually as follows,[cc lang="java"]... XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery("doc('orders.xml')//order[id='174']"); // process the query results ...[/cc]

In the next post, XQJ Part IV, we'll discuss the XQSequence functionality in detail.

An XQExpression object can be reused, each time a different XQuery expression can be executed. The next example retrieves all orders with id 174 and next the orders with id 267,[cc lang="java"]... 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 ...[/cc]

In this last example we execute twice almost the same query, only the value compared against changes.

XQJ supports the concept of prepared queries. The idea here is to "prepare" the query only once, and subsequently "execute" it several times. During the prepare phase, the query is parsed, statically validated and an optimized execution plan is generated. This can be a relative expensive operation, hence 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 with each execution different values to each of the external variables. Coming back to the previous example, here is the XQPreparedExpression variant. Note that the XQuery expression is specified when the XQPreparedExpression object is created, not at execute time,[cc lang="java"]... 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(); ...[/cc]

The previous example demonstrated how to bind values to XQPreparedExpression objects, it is also possible to bind values to external variables using XQExpression objects. Suppose you have a DOM tree and want to query it.[cc lang="java"]... Document domDocument = ...; XQExpression xqe = xqc.createExpression(); xqe.bindNode(new QName("doc"), domDocument, null); XQSequence xqs = xqe.executeQuery( "declare variable $doc as document-node(element(*,xs:untyped));" + "$doc//order[id='174']"); // process the query results ...[/cc]

XQuery has the concept of a context item, represented by a "dot" in your queries. In the previous examples we demonstrated values can be bound to XQExpression and XQPreparedExpression objects by name. In XQuery, the context item has no name, as such XQJ defines a name to bind the context item, XQConstants.CONTEXT_ITEM. The next example is similar to the last one, but it binds the DOM document to the initial context item rather than to an external variable. [cc lang="java"]... Document domDocument = ...; XQExpression xqe = xqc.createExpression(); xqe.bindNode(XQConstants.CONTEXT_ITEM, domDocument, null); XQSequence xqs = xqe.executeQuery(".//order[id='174']"); // process the query results ... [/cc]

In a later post, we will come back on binding values to external variables or the context item.

Note that in all the above examples, the XQuery expressions are specified as Java Strings. XQJ also allows to specify an InputStream, as shown in the next example, where the query in the getorders.xquery file is executed,[cc lang="java"]... InputStream query; query = new FileInputStream("home/joe/getorders.xquery") XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery(query); // process the query results ...[/cc]

Interesting to note here is that an xquery can optionally specify the encoding in the query prolog. Good XQJ/XQuery implementations will use that information and properly parse the InputStream. If no encoding is specified, the assumed encoding depends on the implementation, for DataDirect XQuery this is UTF-8.

We know how to execute queries and have introduced the concept of prepared expressions, next in this series we will focus on processing query results, expect XQJ Part IV soon.

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.
Latest Stories in
Your Inbox
More From Progress
Technical and Security Overview of Progress NativeChat
Download Whitepaper
Putting the Health of Consumers in Their Hands
Download Whitepaper
5 Architecture Considerations for Highly Innovative CIOs
Watch Webinar