XPath для выбора элемента на основе текста в родительском или любого из его дочерних элементов - PullRequest
0 голосов
/ 01 июля 2018

Есть ли способ выбрать элемент, если этот элемент или любой из дочерних элементов имеет определенный текст?

Например, вот два примера:

Пример 1:

<div title='Title1'>
  <input type='checkbox'>
  "Tag 1"
</div>

Пример 2:

<div title='Title2'>
  <input type='checkbox'>
  <span>Tag 1<span>
</div>

Я хочу выбрать тег div независимо от того, находится текст внутри интервала или нет.

Но приведенный ниже XPath выбирает диапазон тегов для второго случая.

//*[(contains(text(), 'Tag 1'))]

Есть ли какой-нибудь лучший XPath для выбора div на основе текста внутри родителя или любого из потомков?

1 Ответ

0 голосов
/ 01 июля 2018

Есть ли какой-нибудь лучший XPath для выбора div на основе текста внутри родителя или любого из потомков?

Используйте ., а не text().

//*[contains(., 'Tag 1')]

text() не дает вам «текст» элемента.

Он дает вам список (!) текстовых узлов , которые являются прямыми дочерними элементами текущего узла контекста. Когда узел контекста равен <div> в примере # 2, этот список будет состоять из трех текстовых узлов, содержащих только пробелы. Я выделил их скобками:

<div title='Title2'>[
  ]<input type='checkbox' />[
  ]<span>Tag 1<span>[
]</div>

'Tag 1' является ребенком <span>, а не <div>.

Теперь contains() не принимает списки узлов. Если вы дадите ему список узлов, он будет учитывать только строковое значение самого первого узла в этом списке. Строковое значение узла - это объединение всех содержащихся в нем текстовых узлов, а не только прямых дочерних элементов.

. относится к узлу контекста. В примере №2 это сам <div>. contains() снова преобразует его в строку, но на этот раз эта строка на самом деле содержит Tag 1. Другой способ написать это:

//*[contains(string(.), 'Tag 1')]

Это то, что вы думали text() сделает.

Теперь //* является рекурсивным, это означает, что будут выбраны <div>, <span> и все <div> предки, потому что все они содержат Tag 1 в некоторой точке.

Используйте что-то более конкретное, чем //*, чтобы исправить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...