Что содержит () в XPath?
У меня есть две почти идентичные таблицы, единственное отличие заключается в входном теге в первой:
Таблица 1
<table>
<tbody>
<tr>
<td>
<div>
<input type="text" name="" value=""/>
</div>
</td>
</tr>
</tbody>
</table>
Таблица 2
<table>
<tbody>
<tr>
<td>
<div></div>
</td>
</tr>
</tbody>
</table>
</body>
Когда я использую этот XPath //table//tbody//tr[position()=1 and contains(.,input)]
он возвращает первую строку обеих таблиц, а не только первую строку первой таблицы, как я и ожидал.
Однако этот XPath //table//tbody//tr[position()=1]//input
возвращает только input
в первом.
Итак, что я делаю не так? Почему то же самое input
связано с обеими таблицами? Я неправильно использую .
здесь как-то?
2 ответа
Из-за неудачного выбора названий функций 1 многие люди ошибочно принимают contains()
функция в XPath:
- XPath
contains()
не проверяет наличие элементов. - XPath
contains()
проверяет наличие подстроки.
Следовательно, tr[contains(.,input)]
не делает то, что вы думаете, что делает. Это на самом деле выбирает tr
элементы, строковое значение которых содержит подстроку, равную строковому значению первого непосредственного дочернего элемента input
элемент; см. этот ответ для более подробной информации. (Интересно, что такой предикат упрощается до истины, поскольку иерархическая природа определения строкового значения подразумевает содержание подстроки между строковыми значениями родительских и дочерних элементов.) В любом случае, это явно не ваше намерение.
Чтобы проверить наличие элемента- потомка, используйте .//input
вместо. Это может быть помещено как предикат tr
как ваш первый XPath попытался сделать, если это tr
элементы, которые вы хотите выбрать,
//table//tbody//tr[position()=1 and .//input]
или же table
( как показано @Andersson), если это действительно table
элементы, которые вы хотите выбрать, которые содержат input
потомок элемента:
//table[.//input]
Почему XPath contains()
должен был быть назван string-contains()
1 В контексте XML, который так сильно основан на понятии иерархии, естественно предположить, что содержание относится к иерархическому сдерживанию. Из 24 раз слово содержит появляется в исходной спецификации XPath, 19 раз это означает содержание иерархического узла; только 5 раз это означает сохранение подстроки. Неудивительно, что путаница над contains()
существует. Подстрока XPath contains()
функция должна была иметь имя string-contains ().
Тебе стоит попробовать
//table[.//input]
принести table
узел, который имеет input
потомок