In XQJ Part III we learned how to execute queries. In XQuery, query evaluation results in a sequence. In XQJ, executing a query through XQExpression or XQPreparedExpression returns an XQSequence object. An XQSequence represents an XQuery sequence with in addition a cursor over that sequence.
The application can browse through an XQSequence using the next() method. Initially the current position of the XQSequence is before the first item. next() moves the current position forward and returns true if there is another item to be consumed. Once all items in the sequence have been read, next() returns false.
Let's iterate through a sequence,[cc lang="java"]... XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery("doc('orders.xml')//order[id='174']"); while (xqs.next()) { ... } ... [/cc]
Positioned on an item, the application can retrieve the data using one of the getXXX() methods. To give a taste, we'll go through some of these methods by example.
An application can use getObject() to retrieve the current item of an XQSequence as a Java object. XQJ defines a mapping for each of the XQuery item types to a Java object value.
One of the most common scenario is probably a query returning a sequence of elements. Using getObject(), XQJ defines a mapping to Java DOM elements,[cc lang="java"]... org.w3c.dom.Element employee; XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery("doc(employees.xml)//employee"); while (xqs.next()) { employee = (org.w3c.dom.Element)xqs.getObject(); ... } ...[/cc]
But actually, XQJ defines a mapping for every XQuery type to Java objects, including all the atomic types. Assume for example a query retuning xs:decimal values, using getObject() your Java application retrieves the items as java.math.BigDecimal objects,[cc lang="java"]... java.math.BigDecimal price; XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery( "doc('orders.xml')/orders/order/xs:decimal(total_price)"); while (xqs.next()) { price = (java.math.BigDecimal)xqs.getObject(); ... } ...[/cc]
Suppose you have a query returning atomic values, and want to retrieve a textual representation of these. For example to output to System.out. getAtomicValue() returns a string representation of an atomic value according to the XQuery xs:string casting rules, and throws an exception if the item is a node. In the next example the query returns a sequence of atomic values, note that the items are not all of the same type.[cc lang="java"]... XQExpression xqe = xqc.createExpression(); XQSequence xqs = xqe.executeQuery( "'Hello world!', 123, 1E1, xs:QName('abc')"); while (xqs.next()) { System.out.println(xqs.getAtomicValue()); } ...[/cc]
Beside the DOM, XQJ also provides native support for 2 other popular XML APIs, SAX and StAX. In the next example each of the items is returned to the application through SAX,[cc lang="java"]... ContentHandler ch = ... XQExpression xqe = xqc.createExpression(); XQSequence xqs = xqe.executeQuery( "doc(employees.xml)//employee"); while (xqs.next()) { xqs.writeItemToSAX(ch); } ...[/cc]
Up to now we have seen a number of examples where the application iterates over all the items in the sequence, and retrieves them one-by-one. The XQSequence interface also offers functionality to retrieve the complete sequence within a single call. In the next example, we execute a query and serialize the complete result into a SAX event stream. [cc lang="java"]... ContentHandler ch = ... XQExpression xqe; XQSequence xqs; xqe = xqc.createExpression(); xqs = xqe.executeQuery("doc('employees.xml')//employee"); xqs.writeSequenceToSAX(ch); ...[/cc]
Or in a similar way, read the complete sequence as a StAX event stream.[cc lang="java"]... XQExpression xqe = xqc.createExpression(); XQSequence xqs = xqe.executeQuery("doc('employees.xml')"); XMLStreamReader xmlReader = xqs.getSequenceAsStream(); while (xmlReader.next() != XMLStreamConstants.END_DOCUMENT) { ... } ...[/cc]
Beside exposing the sequence through a SAX or StAX event stream, XQSequence also provides the ability to serialize into a binary or character stream. Here we're entering the arena of XSLT 2.0 and XQuery 1.0 Serialization, that's what the next post will be about.
Last, the above examples all iterate forward through the XQSequence objects. XQJ has also the notion of scrollable sequences, allowing to move both forward and backwards, set the cursor to an absolute position and allowing to iterate through the XQSequence more than once. We'll come back to it later.
digg_skin = 'compact';
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.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites