J'essaie d'apprendre xpath. J'ai regardé l'autre contient () des exemples ici, mais rien qui utilise un opérateur AND. Je n'arrive pas à faire fonctionner ça:
//ul[@class='featureList' and contains(li, 'Model')]
Sur:
...
<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>
...
Vous ne regardez que le premier enfant li
dans la requête que vous avez au lieu de rechercher un élément enfant li
pouvant contenir le texte, 'Model'
. Ce dont vous avez besoin est une requête comme celle-ci:
//ul[@class='featureList' and ./li[contains(.,'Model')]]
Cette requête vous donnera les éléments qui ont une class
sur featureList
avec un ou plusieurs enfants li
qui contiennent le texte, 'Model'
.
J'ai déjà donné mon +1 à la solution de Jeff Yates.
Voici une explication rapide pour laquelle votre approche ne fonctionne pas. Cette:
// ul [@ class = 'featureList' et contient (li, 'Model')]
rencontre une limitation de la fonction contains()
(ou de toute autre fonction de chaîne dans XPath, d'ailleurs).
Le premier argument est censé être une chaîne. Si vous lui fournissez une liste de noeuds (en lui donnant "li
"), une conversion en chaîne doit avoir lieu. Mais cette conversion est effectuée uniquement pour le premier nœud de la liste.
Dans votre cas, le premier noeud de la liste est <li><b>Type:</b> Clip Fan</li>
(converti en chaîne: "Type: Clip Fan
"), ce qui signifie que:
// ul [@ class = 'featureList' et contient (li, 'Type')]
serait effectivement sélectionner un noeud!
Ceci est une nouvelle réponse à une vieille question sur un idée fausse commune à propos de contains()
dans XPath ...
Résumé: contains()
signifie contient une sous-chaîne, pas contient un nœud.
Ce XPath est souvent mal interprété:
//ul[contains(li, 'Model')]
Mauvaise interprétation: Sélectionnez ces ul
éléments qui contiennent un li
élément avec Model
dedans.
C'est faux parce que
contains(x,y)
s'attend à ce que x
soit une chaîne, etla règle XPath pour convertir plusieurs éléments en une chaîne est this :
Un ensemble de nœuds est converti en une chaîne en renvoyant la valeur valeur-chaîne du nœud de l'ensemble de nœuds ayant la première position dans ordre du document . Si l'ensemble de nœuds est vide, une chaîne vide est renvoyée.
Interprétation correcte: Sélectionnez ces ul
éléments dont premierli
enfant a un chaîne-valeur que contient une sous-chaîne 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')]
sélectionne l'élément one
ul
.
Remarque: L'élément two
ul
n'est pas sélectionné car la valeur de chaîne du premier li
enfant de la two
ul
est Foo
, qui ne contient pas la sous-chaîne Model
.
//ul[li[contains(.,'Model')]]
sélectionne les éléments one
et two
ul
.
Remarque: Les deux éléments ul
sont sélectionnés car contains()
est appliqué à chaque li
individuellement. (Ainsi, la règle de conversion délicate de plusieurs éléments en chaînes est évitée.) Les deux éléments ul
ont un enfant li
dont la valeur de chaîne contient la chaîne Model
. li
l'élément n'a plus d'importance.
//ul[@class="featureList" and li//text()[contains(., "Model")]]