XPath с необязательным элементом в иерархии - PullRequest
34 голосов
/ 06 января 2011

Как и в этом ответе переполнения стека представьте, что вам нужно выбрать конкретную таблицу, а затем все ее строки.Из-за вседозволенности HTML все три из перечисленных ниже являются допустимой разметкой:

<table id="foo"><tr>...</tr></table>
<table id="foo"><tbody><tr>...</tr></tbody></table>
<table id="foo"><tr>...</tr><tbody><tr>...</tr></tbody></table>

Вы беспокоитесь о таблицах, вложенных в таблицы, и поэтому не хотите использовать XPath, такой как
table[@id="foo"]//tr.

Если вы можете указать желаемый XPath в качестве регулярного выражения, оно может выглядеть примерно так:
table[@id="foo"](/tbody)?/tr

В общем, как вы можете указать выражение XPath, которое позволяетНеобязательный элемент в иерархии селектора?

Чтобы было ясно, я не пытаюсь решить реальную проблему или выбрать конкретный элемент конкретного документа.Я прошу методы для решения класса проблем.

Ответы [ 3 ]

22 голосов
/ 06 января 2011

Я не понимаю, почему вы не можете использовать это:

//table[@id='foo']/tr|//table[@id='foo']/tbody/tr

Если вы хотите одно выражение без объединения набора узлов:

//tr[(.|parent::tbody)[1]/parent::table[@id='foo']]
7 голосов
/ 06 января 2011

Использование :

   //table[@id="foo"]/*[self::tbody or self::thead or self::tfoot]/tr
   |
   //table[@id="foo"]/tr

Выберите любой элемент tr, который является дочерним по отношению к любому table, который имеет атрибут id "foo" или любой trэлемент, который является потомком tbody, который является дочерним элементом любого table.

5 голосов
/ 02 сентября 2016

В XPath 2.0 необязательный шаг может быть выражен как (tbody|.).

//table[@id="foo"]/(tbody|.)/tr

Демонстрация XPathTester.com

pipe (|) обозначает union (из двух наборов узлов), dot (.) обозначает шаг идентификации (возвращая только то, что делал предыдущий шаг).

Это можно расширить, добавив сразу несколько дополнительных элементов:

//table[@id="foo"]/(thead|tbody|tfoot|.)/tr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...