“JXPath”:http://jakarta.apache.org/commons/jxpath/ is a Java API to allow “XPath”:http://www.w3.org/TR/xpath queries on Java object hierarchies. My first reaction was “fantastic!”. I’m a “fan(magpiebrain – What XPath is, and why its a Good Thing)”:http://www.magpiebrain.com/archives/000106.html of the simplicity of XPath but have had little need to use it (as in my day-to-day work I don’t use much XML), and initially I thought that JXPath would enable me to use XPath in other areas. After thinking about it for a while I came to realise that the only places in which I actually use a query language is when querying my persistence engines, which all being relational use SQL or something similar (for example EJB-QL or Hibernate-QL). To use JXPath I’d have to load the entire data structure to be queried into an object graph prior to being queried, as very few databases support XPath natively.
You could of course use your XPath queries within your code as Michael Nascimento Santos “points out(JXPath to rescue!)”:http://weblogs.java.net/pub/wlg/864, however I think the notion of replacing java code with Strings just to reduce the size of your code is probably not a great idea. I for one would rather have verbose Java code (which would in all likelihood run faster) than use an XPath query either embedded as a string in the code itself or maintained in a separate location. If the query is likely to change at runtime its a different matter of course.
All of this did start me thinking about something else though. I have been looking at Java-based rule engines of late, most notably Drools. Drools has you define your rules within a configuration file, for example I might code a condition that states if a customer’s wage is more than a certain amount, I make them a special customer (note I’m simplifying the code a little):
user.getWage() > 25000 ... user.setSpecial(true);
Here the condition certainly lends itself to the use of XPath, or at least the use of embedded XPath query using JXPath might be of benefit. I might talk to the Drools guys about this unless I realise its a stupid idea or I get distracted by something else…
4 Responses to “JXPath and Rule Engines”
Yah, at one time we had an XML Semantic Module that used XPaths (jaxen.org, of course, being another bob-project) for the conditions. Either JXPath or jaxen + a javabean navigator could allow you to use xpaths for conditions upon any object graph. Another useful idea might be to create an OGNL semantic module.
Incidentally using the Groovy semantic module for rules in Drools you can use Groovy’s GPath which is similar to XPath in some ways but with a more Java / Groovy / Ruby twist (using closures and property / method navigation).
Its good to know it wasn’t a completely stupid idea on my part then 🙂
Not a stupid idea at all. In a perfect world, your compiler could emit all of the boring Java code required when it encounters a JXPath statement, but even without automagic generation, it’s probably worth the overhead of parsing and interpretation because it reduces the total amount of code and should simplify maintenance, especially as the object model evolves.
I think the reason for JXPath is that it’s easier to get a correct [J]XPath statement then the equivalent lines of Java code, especially if your object model is oriented towards navigation. Looking at the source code for one commercial product I’m involved with, I see a lot of iteration and groveling over objects and the links between them. It’s all straightforward code, but there’s a lot of it.
The other advantage of [J]XPath is that you can write the statements to be more general and can accomodate minor object model changes without rewriting lots of code. Judiciously used, wildcards, for example, should allow the structure of an app’s object model to be changed, e.g. if a library app changes a patron class from pointing directly at a list of checked out books to a list of circulating books with each instance pointing to the patron and book. [Hard to describe without a whiteboard and handwaving.]
I’m not sure straight Java code works as well with object models that reify (convert into objects) relationships between objects. That is, if you have a class for “BooksCheckedOutBy” with instances that refer to each pair of patron and book, you can find all checked-out books by students using a statement like:
/Student[Type=”Student” and @Name = “/CheckedOut/Patron”]
[I may have painted myself in a corner here — this can’t be right — and it may take two statements to do a join like this.]
and still get sensible results whether type is single-valued or allows multiple values. Code to do this is a lot harder to write; witness the growth of Lisp’s LOOP macro from a simple for-next style loop to a complete list/graph iteration construct.
Previous navigation cure-alls have used SQL-like syntax. For hierarchically-structured graphs, [J]XPath seems to make more sense.