[jdom-interest] XPath class
Hallvard Tratteberg
hal at idi.ntnu.no
Thu Mar 14 00:17:06 PST 2002
Jason,
> Laurent Bihanic wrote an XPath class that wraps an XPath engine (aka
> Jaxen) and makes it real easy to get going with XPath. I've attached it
> for comments, before I check it in.
I've been using XPath with JDOM for a while and I certainly find it very
convenient for navigating in a document. In my XPath wrapper I've added
caching of xpath expressions, to reduce the cost of using strings constants
instead of Xpath fields. The idea is to lookup an expression string and
return a prebuilt Xpath in case of match, or else create, cache and return
an existing one:
private static Map xpaths = new Hashtable();
public static XPath makeXPath(String s) throws JDOMException {
try {
XPath xp = null;
if (xpaths.containsKey(s))
xp = (XPath)(xpaths.get(s));
else {
xp = new RhinoXPath(s);
xpaths.put(s, xp);
}
return xp;
}
catch (SAXPathException ex1) {
throw (new JDOMException(
"Invalid XPath expression: \"" + expr + "\"", ex1));
}
}
public static XPath makeXPath(String s, Object args[]) throws
JDOMException
{ return makeXPath(MessageFormat.format(s, args));}
Caching xpath objects loses if many expressions are dynamically generated,
e.g. to handle different predicates. This can be handled by using xpath
variables, e.g. use makeXPath("/game/thing[@owner=$playerId") instead of
makeXPath("/game/thing[@owner='"+playerId+"']"). This requires a function
for setting xpath variables, before the xpath is used for selecting nodes.
My function looks (something) like this:
public void setVariable(String var, Object val)
{
Object o = xpath.getVariableContext();
if (o instanceof SimpleVariableContext)
((SimpleVariableContext)o).setVariableValue(null, var, val);
}
> We pondered a bit together about if it was better to use a separate
> class for this or to add the methods on Element, Attribute, Document, etc.
I like the suggestion of having a separate class in a org.jdom.xpath
package. It may however be better to define an xpath interface or abstract
class and put implementation specific classes in specific packages, like
org.jdom.xpath.jaxen for Laurent's code. Jaxen itself does it this way to
interface to dom and jdom.
When speaking of extensions. I've been working with the Rhino javascript
implementation and have defined classes and methods for making jdom objects
look like javascript objects, manage scripts embedded in xml documents and
use xpath in javascript and vica versa. I imagine this could be packaged as
a contrib. Do you have any thoughts on adding an ord.jdom.scripting package?
Hallvard
More information about the jdom-interest
mailing list