Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Introducing XQJ: A Java API for XQuery

Developers already familiar with JDBC will quickly become comfortable working with XML through XQJ.

Query is a declarative language for querying XML that's similar to SQL for querying relational data. Most Java developers are familiar with JDBC, which provides a standard Java API to interact with a variety of SQL engines operating against relational data sources. XQJ has the same goal: It provides Java developers with a standard Java API for interacting with a variety of XQuery engines operating on XML data sources.

XQJ is also referred to as JSR 225 because it is designed through the Java Community Process (JCP). The JSR 225 specification defines a set of interfaces and classes that enable Java applications to submit XQuery queries against one or more XML data sources to an XQuery engine and consume the results. This article provides an introduction to XQJ by showing a basic use-case example and discussing several key interfaces in XQJ that underlie XQuery concepts. In addition, the article highlights how XQL differs from JDBC.

Fortunately for developers already familiar with JDBC, XQJ follows several familiar patterns. The typical code sequence to perform a query—obtaining a connection, preparing XQuery expressions, binding values to variables in the prepared XQuery expressions, executing the expressions, consuming the XQuery result and cleaning up resources—is exactly the same as that of JDBC. However, several key concepts in XQuery require creating specific interfaces in XQJ, such as the static context, dynamic context, the XQuery data model, and XQuery Sequence Type. Furthermore, one of the main items in the XQuery data model is the XML node. XQJ needs to integrate with existing XML node manipulation APIs such as DOM, SAX, and StAX. XQuery allows nodes to be typed using XMLSchema. XQJ defines it's relationship with XMLSchema through the XQuery Sequence Type interface.

A Basic Example
Here's a basic code example that uses XQJ to execute a query that illustrates a typical use. Note that error handling has been omitted for clarity.

// obtain an XQDataSource instance XQDataSource xqds = (XQDataSource) Class.forName("com.jsr225.xqj").newInstance(); // obtain a connection XQConnection con = xqds.getConnection("usr", "passwd"); // prepare an XQuery Expression String xqry = "for $i in fn:collection('dept') " + "where $i/deptname = %dname return count($i/employees)"; XQPreparedExpression expr = con,preparedExpression(xqry); // bind variable with value expr.bindString(new Qname("dname"), "engineering"); // execute the XQuery Expression XQResultSequence rs = expr.executeQuery(); // Consume results while (rs.next()) { System.out.printLn(rs.getInt()); } // clean up resources rs.close(); con.close();

In the preceding code, XQDataSource is an interface from which you obtain XQuery connections. You can create the initial implementation class for the XQDataSource interface via a typical data source instantiation mechanism, such as JNDI look up or an explicit class-loading method. This is similar to the design of JDBC's DataSource and Connection interfaces.

After obtaining an XQConnection, you execute the XQuery using either the XQExpression or XQPreparedExpression interfaces. You'd use XQExpression when you want to execute an XQuery expression once, and XQPreparedExpression when you want to prepare the XQuery expression once and execute it multiple times with different bind values, as illustrated in the preceding example. These two interfaces are similar to the concepts of Statement and PreparedStatement in JDBC, respectively.

An XQuery result is an instance of the XQuery data model. The XQResultSequence shown in the example provides a cursor-centric interface that allows users to iterate through each item in the result sequence. Users can obtain values from each item, either atomic values or XML nodes. This is similar to iterating through a JDBC result set.

After consuming the XQuery results, developers need to clean up the resources by calling the close() method on the XQResultSequence and XQConnection interfaces. Proper error-handling code for releasing resources is critical to avoid resource leakage. The framework implicitly closes items created from the sequence result when the sequence result is closed. Similarly, the sequence result is implicitly closed if the connection is closed.

Editor's Note: The authors of this article are current or former Oracle employees. We felt this article had sufficient technical merit to warrant publication on DevX.

Comment and Contribute








