mellow-yellow
mellow-yellow

Reputation: 1810

immediately preceding-sibling must contain attribute

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

Answers (1)

John Bollinger
John Bollinger

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

Related Questions