Reputation: 1810
Here is my XML file:
<w type="fruit-hard">apple</w>
<w type="fruit-soft">orange</w>
<w type="vegetable">carrot</w>
I need to find carrot's immediately preceding sibling whose type is fruit-soft. In Chrome (locally loaded XML file), when I try
$x("//w[@type='vegetable']/preceding-sibling::w[1]")
I get "orange" element node like I want, but how do I require that its type be "fruit-soft"? My attempt (below) returns "false."
$x("//w[@type='vegetable']/preceding-sibling::w[1] and preceding-sibling::w[@type='fruit-soft']")
Upvotes: 1
Views: 67
Reputation: 180211
Your original XPath ...
//w[@type='vegetable']/preceding-sibling::w[1]
... is equivalent to
//w[@type='vegetable']/preceding-sibling::w[position()=1]
. You can add additional criteria to the predicate as needed:
//w[@type='vegetable']/preceding-sibling::w[position()=1 and @type='fruit-soft']
Or you can add an add a separate predicate
//w[@type='vegetable']/preceding-sibling::w[1][@type='fruit-soft']
Note that this attempt:
//w[@type='vegetable']/preceding-sibling::w[1] and preceding-sibling::w[@type='fruit-soft']
returns false
because the parts on either side of the and
are evaluated separately, converted to type boolean
, and combined to yield the final result. Supposing that the context node against which that is evaluated is the document root, there will never be a node matching preceding-sibling::w[@type='fruit-soft']
. Moreover, even if there were such a node, that expression does not require nodes matching the first part to be the same ones that matches the second part.
Upvotes: 2