Cirrus Cirrus - 1 month ago 8
HTML Question

XPath for all child elements before a certain sibling?

I have a HTML file looks like below:

<r>
<ab id = "1">
<event/>
<li>a</li>
<li>b</li>
<action/>
<li>a2</li>
<li>b2</li>
<action/>
</ab>
<ab id = "2">
<event/>
<li>a3</li>
<li>b3</li>
<action/>
</ab>
</r>


What I would like to do is first find all event node in the html file, then for every event node find all following sibling nodes until it meets action node. So, for the first event node, the result should be

<li>a</li>
<li>b</li>


And for the second event node, the result should be

<li>a3</li>
<li>b3</li>


For the first step, I used

/r/ab/event


and get the desired result, however, I get stuck and confused in the second step, I have tried to use

following-sibling::*[following-sibling::action[1]]


It gives me the result

<li>a</li>
<li>b</li>
<action/>
<li>a2</li>
<li>b2</li>


for the first event node, and the result

<li>a3</li>
<li>b3</li>


for the second event node.

Any idea of how to solve this problem?
Also, I guess I may misuse following-sibling inside the predicates, I have looked at the documentation, https://www.w3.org/TR/xpath, but didn't quite understand how to use it, can anyone help to explain a little bit?

Answer

This XPath

/r/ab/event/following-sibling::li[not(preceding-sibling::action)]

will select all li elements that follow event elements and do not have a preceding action element sibling,

<li>a</li>
<li>b</li>
<li>a3</li>
<li>b3</li>

as requested.

Comments