Как использовать XPath содержит() здесь?
Я пытаюсь изучить xpath. Я посмотрел на другие примеры contains(), но ничего не использовал оператор AND. Я не могу заставить это работать:
//ul[@class='featureList' and contains(li, 'Model')]
О:
...
<ul class="featureList">
<li><b>Type:</b> Clip Fan</li><li><b>Feature:</b> Air Moved: 65 ft.
Amps: 1.1
Clip: Grips any surface up to 1.63"
Plug: 3 prong grounded plug on heavy duty model
Usage: Garage, Workshop, Dorm, Work-out room, Deck, Office & more.</li><li><b>Speed Setting:</b> 2 speeds</li><li><b>Color:</b> Black</li><li><b>Power Consumption:</b> 62 W</li><li><b>Height:</b> 14.5"</li><li><b>Width:</b> Grill Diameter: 9.5"</li><li><b>Length:</b> 11.5"</li>
<li><b>Model #: </b>CR1-0081-06</li>
<li><b>Item #: </b>N82E16896817007</li>
<li><b>Return Policy: </b></li>
</ul>
...
Ответы
Ответ 1
Вы смотрите только на первый li
дочерний объект в запросе, который вы используете вместо поиска дочернего элемента li
, который может содержать текст 'Model'
. Вам нужен запрос следующего типа:
//ul[@class='featureList' and ./li[contains(.,'Model')]]
Этот запрос предоставит вам элементы с class
из featureList
с одним или несколькими дочерними элементами li
, которые содержат текст 'Model'
.
Ответ 2
Я уже отдал свое решение +1 Джеффу Ятес.
Вот краткое объяснение, почему ваш подход не работает. Это:
//ul[@class='featureList' and contains(li, 'Model')]
встречается ограничение функции contains()
(или любая другая строковая функция в XPath, если на то пошло).
Первый аргумент должен быть строкой. Если вы его подаете, список node (дающий ему "li
" делает это), должно произойти преобразование в строку. Но это преобразование выполняется для первого node только в списке.
В вашем случае первый node в списке <li><b>Type:</b> Clip Fan</li>
(преобразованный в строку: "Type: Clip Fan
" ), что означает, что это:
//ul[@class='featureList' and contains(li, 'Type')]
действительно выберет node!
Ответ 3
Это новый ответ на старый вопрос о распространенном заблуждении о contains()
в XPath...
Резюме: contains()
означает, что содержит подстроку, а не содержит узел.
Детальное объяснение
Этот XPath часто неверно истолковывается:
//ul[contains(li, 'Model')]
Неправильная интерпретация: выберите те элементы ul
которые содержат элемент li
с Model
.
Это неправильно, потому что
-
contains(x,y)
ожидает, что x
будет строкой, и -
правило XPath для преобразования нескольких элементов в строку таково:
Набор узлов преобразуется в строку, возвращая строковое значение узла в наборе узлов, который является первым в порядке документа. Если набор узлов пуст, возвращается пустая строка.
Право интерпретации: Выберите те ul
элементы, первый li
ребенок имеет строковое значение, которое содержит Model
подстроку.
Примеры
XML
<r>
<ul id="one">
<li>Model A</li>
<li>Foo</li>
</ul>
<ul id="two">
<li>Foo</li>
<li>Model A</li>
</ul>
</r>
XPaths
-
//ul[contains(li, 'Model')]
выбирает one
элемент ul
.
Примечание. Элемент two
ul
не выбран, поскольку строковое значение первого дочернего элемента li
two
ul
- Foo
, которое не содержит подстроку Model
.
-
//ul[li[contains(.,'Model')]]
выбирает one
и two
элемента ul
.
Примечание. Оба элемента ul
выбраны, так как contains()
применяется к каждому li
отдельности. (Таким образом, исключается сложное правило преобразования нескольких элементов в строку.) Оба элемента ul
имеют дочерний элемент li
, значение строки которого содержит подстроку Model
- положение элемента li
больше не имеет значения.
Смотрите также
Ответ 4
//ul[@class="featureList" and li//text()[contains(., "Model")]]
Ответ 5
Вставьте сюда пример contains
:
//table[contains(@class, "EC_result")]/tbody