[jdom-interest] XPath examples
Rolf Lear
jdom at tuis.net
Wed May 30 13:26:24 PDT 2012
Hi Peter,
Yes, the examples are sparse. A few things though: Check out
https://github.com/hunterhacker/jdom/wiki/JDOM2-Feature-XPath-Upgrade
That gives an overview of the changes in XPath processing in JDOM 2.x
As for your comment on having a compile(expression, namespace, filter)
method, I think that you are 'over-thinking' the problem, and even if
you do need a namespace, then the existing compile method would work
well too:
http://www.jdom.org/docs/apidocs/org/jdom2/xpath/XPathFactory.html#compile%28java.lang.String,%20org.jdom2.filter.Filter,%20java.util.Map,%20org.jdom2.Namespace...%29
You just need to add a null value for the variable Map... like:
compile(expression, filter, null, namespace);
The Javadoc on that compile method is fairly comprehensive... even if
only on the technical side, and not so much the 'example' side I think.
Now, about the broader concept of variables.... XPath allows you to use
variables in your expression. For example, you could have the 'simple'
XPath query:
//emt[@name = 'hello']
Which would select all elements with an attribute called 'name' where
the 'name' attribute's value is 'hello'.
You could build a JDOM XPathExpression with:
XPathExpression<Element> xp = XPathFactory.instance().
compile("//emt[@name = 'hello']", Filter.element());
However, perhaps you want to check for a different 'name' each time, you
could then change the XPath query to:
//emt[@name = '$varname']
Now, as soon as your XPath has variables, you need to define them when
you compile....
Map<String,Object> vars = new HashMap<String,Object>();
vars.put("name", null);
XPathExpression<Element> xp = XPathFactory.instance().
compile("//emt[@name = '$varname']", Filter.element(), vars);
Then you need to give the variable a value before you use the XPath
expression:
xp.setVariable("varname", "hello");
Then if you evaluate the expression it will return 'emt' elements with
the attribute name="hello".
If you change the variable again:
xp.setVariable("varname", "world");
... when you evaluate the expression it will return 'emt' elements with
the attribute name="world".
Note, I have not used any namespaces in these examples.
The XPathBuilder in theory could make it easier to create a complex
XPath expression by 'encapsulating' the XPath process prior to compiling it.
The same variable example could be:
XPathBuilder<Element> xpb = new XPathBuilder(
"//emt[@name = '$varname']", Filter.element()
xpb.setVariable("varname", "hello");
XPathExpression<Element> xp = xpb.compileWith(XPathFactory.instance());
If your XML Document has Namespaces then you will probably need to have
namespaces as part of your XPath expression...
For example, if the actual XML Document is:
<root xmlns="http://example.org">
<emt name="hello" />
<emt name="world" />
</root>
then the root and both emt elements are in the 'http://example.org'
namespace. To select these using an XPath you will need to identify
their namespace... the simple XPath query '//emt' will return *nothing*.
You need a namespace-correct XPath query.
In this case, we need a namespace-prefixed query: '//ns:emt' with prefix
'ns' mapped to 'http://example.org'. Note how I simply 'created' the
namespace prefix 'ns'. Like othr namespace prefixes, it does not matter
what the actual prefix is, just the URI. There is one core concept
though in XPaths.... that the "" empty-string prefix is *always* mapped
to the "" empty-string URI.... there is no such thing as a 'default'
namespace in an XPath query.
To do this in JDOM you would do:
XPathExpression<Element> xp = XPathFactory.instance().
compile("//ns:emt", Filter.element(), null,
Namespace.getNamespace("ns", "http://example.org"));
The concepts of Namespace and Variables in XPath are 'orthogonal',
although variables themselves may have a namespace... I guess they are
not totally orthogonal.
Hope this helps ....
Rolf
On 30/05/2012 3:10 PM, Peter Kronenberg wrote:
> Where can I find some more examples of Xpath usage in JDOM2? The online
> documentation is a bit sparse.
>
> I’m specifically confused about how the variables are used. And if I’m
> not using variables, it seems that I must use the XPathBuilder to set
> the namespace. Wouldn’t it make sense for XPathFactory to have a
> compile(String expression, Namespace ns, Filter filter) version?
>
> Or XPathExpression could have a setNamespace() method.
>
> Thanks
>
> Peter Kronenberg
>
> Software Engineer
>
> Technica Corporation
>
> pkronenberg at technicacorp.com <mailto:pkronenberg at technicacorp.com>
>
> 703.885.1222 (Office)
>
More information about the jdom-interest
mailing list