Я пытаюсь изучить 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>
...
Вы смотрите только на первый li
дочерний объект в запросе, который вы используете вместо поиска дочернего элемента li
, который может содержать текст 'Model'
. Вам нужен запрос следующего типа:
//ul[@class='featureList' and ./li[contains(.,'Model')]]
Этот запрос предоставит вам элементы с class
из featureList
с одним или несколькими дочерними элементами li
, которые содержат текст 'Model'
.
Я уже отдал свое решение +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!
Это новый ответ на старый вопрос о распространенном заблуждении о contains()
в XPath...
Сводка: contains()
означает, что содержит подстроку, не содержит node.
Этот XPath часто неверно интерпретируется:
//ul[contains(li, 'Model')]
Неверная интерпретация:
Выберите те элементы ul
, которые содержат элемент li
с Model
в нем.
Это неправильно, потому что
contains(x,y)
ожидает, что x
будет строкой, аПравило XPath для преобразования нескольких элементов в строку this:
A node -set преобразуется в строку, возвращая string-value of node в node -set, который сначала находится в порядок документа. Если node -set пуст, возвращается пустая строка.
Правильная интерпретация: Выберите те элементы 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
больше не вопросы.
Вставьте сюда пример contains
:
//table[contains(@class, "EC_result")]/tbody
EC_result
OP нет элемента table
или EC_result
класса EC_result
. Этот ответ не имеет смысла здесь и должен быть удален.