[jdom-interest] XPath examples

Rolf Lear jdom at tuis.net
Wed May 30 14:21:08 PDT 2012


Hi Peter

One of the issues with using var-args for the Namespace is that it 
becomes ambiguous if I take away the 'Variables' argument.... so it 
would not work to add a new method without the variables map.

In my head when I put the two major compile methods together, it was 
'simple' and 'complex' xpaths .... simple have no variables and 
Namespaces. Complex ones do....


As for whether the variables have to be XPath values.... I believe so - 
it would not make sense of the variable value is expected to be 
'compiled', and that maks me realize that I got the examples wrong.... 
there should not be quotes around the $varname in the examples I gave....

Yes, reading the XPath syntax here: 
http://www.w3.org/TR/xpath/#NT-VariableReference

The variable reference is only allowed to be a discrete part of the 
query, and additionally, it later says:

The variable bindings consist of a mapping from variable names to 
variable values. The value of a variable is an object, which can be of 
any of the types that are possible for the value of an expression, and 
may also be of additional types not specified here.

which implies that the variable value is not re-evaluated

On 30/05/2012 4:48 PM, Peter Kronenberg wrote:
> 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)



More information about the jdom-interest mailing list