Given an xml document like this:
<node>
<node text="text1" x=400 y=400></node>
</node>
<node>
<node text="text1" x=400 y=900></node>
</node>
<node>
<node text="text2" x=400 y=1000></node>
</node>
... etc ...
How would I write an xpath query to select the node where the text attribute is "text1" with the greatest value for y (in this case 900)? I don't know exactly what the y value will be, but I do know that the node I am always supposed to be selecting is the one with the higher y value, and that the two nodes will not be siblings. Aside from the y value, the two nodes I'm trying to differentiate between will have all attributes equal.
答案 0 :(得分:3)
Your input document is not well-formed. It lacks a single outermost (root) element and some of the attribute values have no quotes. Given a well-formed input document like this:
<root>
<node>
<node text="text1" x="400" y="400"></node>
</node>
<node>
<node text="text1" x="400" y="900"></node>
</node>
<node>
<node text="text2" x="400" y="1000"></node>
</node>
</root>
The following XPath expression:
//node[@text = 'text1' and not(@y < preceding::node[@text = 'text1']/@y or @y < following::node[@text = 'text1']/@y)]
finds the node
element(s) that has text1
and the highest value in @y. In this case, the only result is
<node text="text1" x="400" y="900"/>
In more detail, the path expression means
//node select all `node` elements, anywhere in
the document
[@text = 'text1' but only if its `text` attribute is
equal to "text1"
and not(@y < preceding::node[@text = 'text1']/@y and only if the value of its `y`
attribute is not lower than the value
of an `y` attribute of another `node`
element of the same sort that precedes
the current one
or @y < following::node[@text = 'text1']/@y)] and only if the value if its `y`
attribute is not lower than the value
of an `y` attribute of another `node`
element of the same sort that follows
the current one
EDIT: Alternatively, use
//node[@text="text1" and not(//node[@text="text1"]/@y > @y)]
as splash58 has suggested. The semantics of this expression are very similar to the one above.