Advertisment

Querying Objects and Object Hierarchies

author-image
PCQ Bureau
New Update

JXPath is a module in the Apache Commons Library that lets you query object

hierarchies using the Xpath-based syntax. XPath (XML Path Language) is a

standard part of the XSLT and is used for accessing elements of a XML document

in XSLT. JXPath allows the same and a lot more such as reading/writing beans

properties, get/set elements of arrays, collections and other data structures

and even various contexts such as JSP Page context, Servlet contexts, and

HTTPSession contexts. Using JXPath eliminates the need to use iterators and

conditional blocks for narrowing down on your objects. All that is required for

the API to work with Java objects is that these objects should have

getter/setter methods and should return standard collections (array, list,

collection, and set). In this article, we will look into how it changes things

around when used.

Advertisment
Applies To: Java developers



USP: Using JXPath for querying object sets


Primary Link: jakarta.apache.org/commons/jxpath/


Google Keywords: XPath, JXPath

XPath expressions



We'll briefly talk of XPath expressions before we go into the details of
JXPath. XPath can represent object or element hierarchies using simple path like

annotations. For example, to get (say) all the products, we use '/products'

command. To get a particular category say 'category1' under 'products'

you can use

/products/category1

Advertisment

The expression for predicated queries can be exemplified as follows.

/products/linen

The query will give you all the linen-based apparels. It is beyond the limits

of this article to cover XPath substantially. So for more information, you can

refer to http://www.w3.org/TR/xpath.html.

Advertisment

Using JXPath



You can download the latest binaries (version 1.2) from the URL http://jakarta.apache.org/site/downloads/downloads_commons.html
and unzip the compressed file to any location on your hard drive. Include the

commons-jxpath-1.2.jar file in your IDE environment or classpath, and that's

all for setup. Let us take a code sample for querying. We are assuming a set of

objects representing products, their type and categories in a store. The

products could be anything from eatables, to apparels, to anything. Following is

the code for querying to find the name of product coded '001' which is of

type eatable and is located in the 'quick-bites' stall.

Iterator products = getproducts().iterator();



while(product.hasNext()){


Product product = products.next();


If(product.getStall().equals(“quick_bites”){


....


//code for further querying


}}




Using JXPath, the code is reduced to the following

Advertisment

JXPathContext context =

JXPathContext.getContext(product);



String name = context.getValue(“/product/code='001'>”);

The advantages that we get here arethat the code is a lot shorter and you can

parameterize the expression used (that is, you could use variables for



location and code values or put all of this in a configuration file). The code
uses JXPathContext class that is central to this API and provides APIs for

traversal of object graphs. JXPathContext allows alternative implementations.

This is why instead of allocating JXPathContext directly, we call a static

newContext() method.

JXPath also allows querying nested beans. For example, if we have an Employee

Bean with a nested 'Address' bean, you can use JXPath to traverse to the

nested bean and query it for its properties. This is done using JXPath as

follows.

Advertisment

public class Employee{



private Address;


....


public Address getAddress(){


...


}}


public class Address{


public String getStreetName(){


....


}}


Employee emp = new Employee();


....


JXPathContext context = JXPAthContext.newContext(emp);


String street = (String) context.getVAlue(“address/streetName”);











Here, the last statement is querying on the streetNumber property of the

address bean. There is a difference between accessing a node and accessing that
property or node's value while using JXPath with DOM/JDOM objects. Let's

consider an XML document.








ND771




Advertisment

The expression getVAlue (“agent/code”) will return the value 'ND771'

while selectSingleNode (“agent/code”) will return an object if type Element

of DOM/JDOM type, ie ND771

JXPath query exceptions



Accessor method throws exceptions and these exceptions depend upon the evaluated
XPath of particular method. For example, when a query is looking for something

by iterating through objects' properties and during that traversal one of the

accessor methods throws an exception, JXPath ignores them and query moves on to

next property. In all other cases, accessor method exceptions are wrapped in

JXPathException and re-thrown. For example in case one tries to query for a

department's location which practically might not exist, you will get an

exception. You can suppress exceptions in such cases by using the

setLinient(true) method on the context object. The method forces JXPath to

simply return a null value in cases of exception.

In conclusion



There are a lot more scenarios where JXPath will prove to be a better option.
You have seen a few examples of JXPath usage for querying POJOs. The best part

about JXPath is that you can get a lot from it without having to work on or

write codes for Rocket Science. From writing queries for XML documents to

providing expression for server processes, it is less cumbersome when it comes

to JXPath.

Advertisment