wake-up-neo.com

Wie benutzt man XPath enthält () hier?

Ich versuche xpath zu lernen. Ich habe mir die anderen enthält () Beispiele hier angesehen, aber nichts, das einen AND-Operator verwendet. Ich kann das nicht zum Laufen bringen:

//ul[@class='featureList' and contains(li, 'Model')]

Auf:

...
<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>
...
136
ryeguy

Sie suchen nur das erste li untergeordnete Element in der Abfrage, anstatt nach einem li untergeordneten Element zu suchen, das möglicherweise den Text 'Model' Enthält. Was Sie brauchen, ist eine Abfrage wie die folgende:

//ul[@class='featureList' and ./li[contains(.,'Model')]]

Diese Abfrage gibt Ihnen die Elemente mit einem class von featureList mit einem oder mehreren li untergeordneten Elementen, die den Text 'Model' Enthalten.

191
Jeff Yates

Ich habe Jeff Yates 'Lösung bereits meine +1 gegeben.

Hier ist eine kurze Erklärung, warum Ihr Ansatz nicht funktioniert. Diese:

// ul [@ class = 'featureList' und enthält (li, 'Model')]

stößt auf eine Einschränkung der Funktion contains() (oder einer anderen Zeichenfolgenfunktion in XPath).

Das erste Argument soll eine Zeichenfolge sein. Wenn Sie ihm eine Knotenliste zuführen (wenn Sie dafür "li" angeben), muss eine Konvertierung in einen String erfolgen. Diese Konvertierung wird jedoch nur für den ersten Knoten in der Liste durchgeführt.

In Ihrem Fall ist der erste Knoten in der Liste <li><b>Type:</b> Clip Fan</li> (in eine Zeichenfolge umgewandelt: "Type: Clip Fan ") was bedeutet, dass dies:

// ul [@ class = 'featureList' und enthält (li, 'Type')]

würde eigentlich einen knoten auswählen!

57
Tomalak

Dies ist eine neue Antwort auf eine alte Frage zu einem häufigen Missverständnis über contains() in XPath ...

Zusammenfassung: contains() bedeutet enthält einen Teilstring, nicht enthält einen Knoten.

Ausführliche Erklärung

Dieser XPath wird oft falsch interpretiert:

//ul[contains(li, 'Model')]

Falsche Interpretation: Wählen Sie die ul - Elemente aus, die enthalten ein li - Element mit Model drin.

Das ist falsch, weil

  1. contains(x,y) erwartet, dass x ein String ist, und
  2. die XPath-Regel zum Konvertieren mehrerer Elemente in einen String lautet this :

    Eine Knotenmenge wird in eine Zeichenfolge konvertiert, indem Zeichenfolgenwert des Knotens in der Knotenmenge zurückgegeben wird, der an erster Stelle in Dokumentreihenfolge steht. Wenn der Knotensatz leer ist, wird eine leere Zeichenfolge zurückgegeben.

Richtige Interpretation: Wählen Sie die Elemente ul aus, deren firstli Kind hat ein String-Wert dass enthält ein Model - Teilstring ist.

Beispiele

[~ # ~] 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')] wählt das Element oneul aus.

    Hinweis: Das Element twoul ist nicht ausgewählt, da der Zeichenfolgenwert des ersten Elements li untergeordnetes Element von twoul ist Foo, das den Teilstring Model nicht enthält.

  • //ul[li[contains(.,'Model')]] wählt die Elemente one und twoul aus.

    Hinweis: Beide ul - Elemente werden ausgewählt, da contains() auf jedes li einzeln angewendet wird. (Somit wird die schwierige Konvertierungsregel von mehreren Elementen in Zeichenfolgen vermieden.) Beide ul - Elemente haben ein untergeordnetes li - Element, dessen Zeichenfolgenwert die Unterzeichenfolge Model enthält. Die Position des Elements li spielt keine Rolle mehr.

Siehe auch

6
kjhughes
//ul[@class="featureList" and li//text()[contains(., "Model")]]
0
runrig