[jdom-interest] XPath examples

Peter Kronenberg PKronenberg at technicacorp.com
Wed May 30 13:48:56 PDT 2012


Thanks for the quick and comprehensive response.

I guess I realized I could pass null for the variables in the compile() method, but still think it would be a bit cleaner to have a method without the variables, since I almost always uses namespaces and might not be using variables so much.

Do the variables have to be xpath values (i.e., in quotes), or can any part of the xpath expression be put into a variable?

Peter Kronenberg
Software Engineer
Technica Corporation
pkronenberg at technicacorp.com 
703.885.1222 (Office) 

-----Original Message-----
From: Rolf Lear [mailto:jdom at tuis.net] 
Sent: Wednesday, May 30, 2012 4:26 PM
To: Peter Kronenberg
Cc: jdom-interest at jdom.org
Subject: Re: [jdom-interest] XPath examples

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)
>

The information contained in this transmission may contain privileged and confidential information. 
It is intended only for the use of the person(s) named above. 
If you are not the intended recipient, you are hereby notified that any review, dissemination, distribution or duplication of this communication is strictly prohibited. 
If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message. 
Technica Corporation does not represent this e-mail to be free from any virus, fault or defect and it is therefore the responsibility of the recipient to first scan it for viruses, faults and defects. 
To reply to our e-mail administrator directly, please send an e-mail to postmaster at technicacorp.com. Thank you.




More information about the jdom-interest mailing list