XPath для всех дочерних элементов перед определенным родственным?

#html #xml #xpath

#HTML #xml #xpath

Вопрос:

У меня есть HTML-файл, который выглядит следующим образом:

 <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>
  

Что я хотел бы сделать, это сначала найти все узлы событий в html-файле, затем для каждого узла событий найти все последующие родственные узлы, пока он не встретит узел действия. Итак, для первого узла события результат должен быть

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

И для второго узла события результат должен быть

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

Для первого шага я использовал

 /r/ab/event
  

и получить желаемый результат, однако я застрял и запутался на втором шаге, я попытался использовать

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

Это дает мне результат

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

для первого узла события и результат

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

для второго узла события.

Есть идеи, как решить эту проблему? Кроме того, я предполагаю, что могу неправильно использовать следующий sibling внутри предикатов, я просмотрел документацию, https://www.w3.org/TR/xpath, но не совсем понял, как это использовать, кто-нибудь может помочь немного объяснить?

Ответ №1:

Этот XPath

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

будут выбраны все li элементы, которые следуют за event элементами и не имеют предшествующего action родственного элемента,

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

как и было запрошено.