Данный тестовый html:

<html>
<body>
  abc
  <b id="b_1">def</b>
  ghi
  <b id="b_2">jkl</b>
  <b id="b_3">mno</b><b id="b_4">qrs</b>
</body>
</html>

Вопрос: Как я могу выбрать все элементы b, у которых первый предшествующий узел не являются пустыми текстовыми узлами ?

Итак, в приведенном выше примере я хочу выбрать элементы b_1 и b_2.

Элемент b_3 имеет первый предшествующий узел-брат типа text, но он пуст.

У элемента b_4 есть первый предшествующий родственный узел, который является узлом элемента.


Я пробовал следующее, но оба они потерпели неудачу по крайней мере в одном отношении:

  • preceding-sibling::*[1] выберет первый узел элемента, игнорируя нужные текстовые узлы.
  • preceding-sibling::text()[1] выберет первый текстовый узел, пропуская любые узлы элементов.
0
Oleg Golovanov 5 Янв 2018 в 22:28

2 ответа

Лучший ответ

Этот XPath,

//b[preceding-sibling::node()[1][self::text()][.!='']]

Выберет все элементы b, чьим прямым предшествующим братом является непустой текстовый узел:

<b id="b_1">def</b>
<b id="b_2">jkl</b>

Как просили.

2
kjhughes 5 Янв 2018 в 20:42

Это должно работать:

//b[normalize-space(./preceding-sibling::text()[1])]

Функция normalize-space проверяет, что там что-то существует, потому что preceding-sibling может быть пустым или даже просто \n.

-1
Charles Duffy 6 Янв 2018 в 16:35