Пытаюсь изучить 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'
. Вам нужен следующий запрос:Этот запрос даст вам элементы , которые имеют
class
отfeatureList
одной или несколькихli
детей , которые содержат текст,'Model'
.источник
li
withModel
inul
, тоand
условие не выполняется . Итак,and
условие возвращаетсяfalse
на пустой набор, это правильно?Я уже дал свой +1 к решению Джеффа Йейтса.
Вот краткое объяснение, почему ваш подход не работает. Этот:
обнаруживает ограничение
contains()
функции (или любой другой строковой функции в XPath, если на то пошло).Первый аргумент должен быть строкой. Если вы скармливаете ему список узлов (это
li
делает " "), то должно произойти преобразование в строку. Но это преобразование выполняется только для первого узла в списке.В вашем случае первый узел в списке
<li><b>Type:</b> Clip Fan</li>
(преобразован в строку: "Type: Clip Fan
"), что означает, что это:фактически выбрал бы узел!
источник
Это новый ответ на старый вопрос о распространенном заблуждении о
contains()
XPath ...Резюме:
contains()
означает, что содержит подстроку , а не узел .Детальное объяснение
Этот XPath часто неверно интерпретируют:
Неправильная интерпретация: выберите те
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
элемента больше не имеет значения.Смотрите также
источник
источник
Вставьте мой
contains
пример сюда:источник
table
элемента илиEC_result
класса. Этот ответ здесь не имеет смысла и должен быть удален.