JXPath simplifies Java queries

Consider a company that contains many departments. Those departments contain employees, those employees have names, telephone numbers, and so on. To query a collection of companies and find, for example, all departments of companies in California with more than 10 employees, you could write something like this:

for (Iterator companies =
      database.getCompanies().iterator();
      companies.hasNext();) {

   Company company = (Company)companies.next();

   if (company.getLocation().equals("CA")) {

      for (Iterator departments =
            company.getDepartments().iterator();
            departments.hasNext(); ) {

         Department department = (Department)departments.next();

         if (department.getEmployees().size() > 10) {
            System.out.println(department);
         }
      }
   }
}

Using JXPath you can simplify this:

// only needed once
JXPathContext context = JXPathContext.newContext(database);

Iterator departments = context.iterate(
      "/companies[location='CA']" +
      "/departments[count(employees) > 10]");
while (departments.hasNext()) {
   System.out.println(departments.next());
}

Two points should be noted from this example:

  • The code using JXPath is considerably shorter. The query is concisely expressed in one statement.
  • You can take that expression out of the code and parameterize it, or put it in a configuration file.

Perfect for Unit Testing

Unit testing often requires checking object hierarchies for particular values. You can use JXPath to express the components to be tested. For example, you can write a helper method in a JUnit test:

/**
 * tests using a JXPath to express the required
 * component to test against. Note that nulls
 * aren't catered for!
 * @param path the path to find the object to
 *        test against
 * @param testable the base object to test
 * @param required the required result
 */
private void assertFromPath(String path,
                            Object testable,
                            Object required) {

   JXPathContext context = JXPathContext.newContext(testable);
   assertTrue(required.equals(context.getValue(path)));
}

and then you can use this in tests:

public void testBankAccount() {

   // you get a bank account object from some operation...
   Account account = ....

   // then test against it
   assertFromPath("/accountHolder/name", account, "John Smith");
   assertFromPath("/accountHolder/opened", account, DATE_OPENED);
   assertFromPath("/accountHolder" + "/transactions[1]/amount",
         account, INITIAL_PAYMENT);
}

Read more in this java.net article.

This Post Has One Comment

  1. exceptionell plats inlägget. Jag ska bokmärke och kolla in mycket oftare. Jag gillar verkligen webbplats mall

Leave a Reply

Close Menu