Given XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<c cid="c0" v="100">
<d did="c00" v="0" dt="2016-01-01" />
<d did="c01" v="0" dt="2016-02-03" />
<d did="c02" v="0" dt="2016-01-15" />
</c>
<c cid="c1" v="100">
<d did="c10" v="1" dt="2016-01-01" />
<d did="c11" v="0" dt="2015-03-03" />
<d did="c12" v="0" dt="2015-04-15" />
</c>
</root>
I have to find XPath 2.0 or 3.0, which will return to me list of c
nodes by expression: find maximum d
node of this c
children by dt
attribute (parse it as date
), and if its v
attribute value is "0", return the c
node.
I expect to get a one c
node (with @cid="c0") as a result, because /root/c[cid="c1"]/d[@dt="2016-01-01"]/@v
is not equal to 0 (is equal to 1).
I have stuck on this XPath sofar:
/root/c[d[max(xs:date(@dt))]/@v="0"]
It gives me an error (I'm using Oxygen XML Editor, XPath 3.0):
XPath failed due to: Effective boolean value is not defined for a sequence starting with an atomic value other than a boolean, number, string, or URI
I suppose this is due to misused max
function, but cannot get it working.
UPDATES:
c
nodes will have d
children with unique maximum value of their dt
attributes.I also tried XPath 3.0 expression:
/root/c[d[@dt=max(.//@dt/xs:date(.))]/@v="0"]
but it returned me all nodes (wrong result).
Here is a shorter and probably more efficient (the max per a <c>
element is calculated just once) XPath 2.0 one-liner:
/*/c[max(d/xs:date(@dt)) = d[@v eq '0']/@dt]
Enjoy!