Pytanie w sprawie xpath, xml – Jak korzystać z XPath zawiera () tutaj?

127

Próbuję nauczyć się xpath. Obejrzałem tutaj inne przykłady include (), ale nic, co używa operatora AND. Nie mogę tego zrobić:

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

Na:

...
<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>
...
to działa dla mnie, przetestowałem towhitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm mihi
Co dla ciebie działa ryeguy

Twoja odpowiedź

4   odpowiedź
181

Patrzysz tylko na pierwszyli dziecko w zapytaniu, które masz zamiast szukaćli element podrzędny, który może zawierać tekst,'Model'. Potrzebne jest zapytanie takie jak:

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

To zapytanie da ci elementy, które mająclass zfeatureList z jednym lub więcejli dzieci, które zawierają tekst,'Model'.

+1 - „./” jest nieco mylące - sugeruje, że cokolwiek innego niż bieżący węzeł, będzie brane pod uwagę podczas opuszczania go, ale w rzeczywistości jest ono zbędne: „// ul [@ class =” featureList 'i li [zawiera (.,' Model ')]] ”to to samo. Tomalak
Tak, po prostu byłem konkretny. Całkiem możliwe, że zbyt specyficzne. Jeff Yates
Jeżeli nie mali zModel wul, a późniejand warunek się nie powiedzie. Więcand warunek powracafalse na pustym zestawie, czy to prawda? damluar
55

Dałem już +1 do rozwiązania Jeffa Yatesa.

Oto krótkie wyjaśnienie, dlaczego twoje podejście nie działa. To:

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

napotyka ograniczeniecontains() funkcja (lub jakakolwiek inna funkcja łańcuchowa w XPath).

Pierwszy argument ma być ciągiem znaków. Jeśli podasz mu listę węzłów (podając ją)li„robi to”, musi nastąpić konwersja na łańcuch, ale ta konwersja jest wykonywana tylko dla pierwszego węzła na liście.

W twoim przypadku pierwszym węzłem na liście jest<li><b>Type:</b> Clip Fan</li> (przekonwertowane na ciąg: „Type: Clip Fan„), co oznacza, że:

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

wybrałby węzeł!

miło było, że starał się dowiedzieć, dlaczego zapytania takie jak: ".//td[cont((////,'something")] "działają tylko do głębokości 1. Zorientowałem się, jak to zrobić, ale nie było pewnie jak to wszystko działało. To, czego naprawdę potrzebowałem, to „.//td[.//*[contains(.,'something”)]] ” JonnyRaa
6

To nowa odpowiedź na stare pytanie dotyczące apowszechne niezrozumienie ocontains() w XPath ...

Streszczenie:contains() znaczyzawiera podciąg, nie zawiera węzeł.

Szczegółowe wyjaśnienie

Ta XPath jest często błędnie interpretowana:

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

Zła interpretacja: Wybierz teul elementy, którezawierać nali element zModel w tym.

To jest złe, ponieważ

contains(x,y) oczekujex być ciągiem, i

reguła XPath do konwersji wielu elementów na łańcuch jestto:

Zestaw węzłów jest konwertowany na łańcuch przez zwróceniewartość ciągu węzła w zestawie węzłów, który jest pierwszy wkolejność dokumentów. Jeśli zestaw węzłów jest pusty, zwracany jest pusty łańcuch.

Właściwa interpretacja: Wybierz teul elementy, którychpierwszy li dziecko mawartość ciągu żezawiera a Model podciąg.

Przykłady

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')] wybieraone ul element.

Uwaga: Thetwo ul element nie jest wybrany, ponieważ wartość ciągu pierwszegoli dzieckotwo ul jestFoo, który nie zawieraModel podciąg.

//ul[li[contains(.,'Model')]] wybieraone itwo ul elementy.

Uwaga: Obieul elementy są wybierane, ponieważcontains() jest stosowany do każdegoli indywidualnie. (W ten sposób unika się trudnej reguły konwersji wielu elementów na łańcuch)ul elementy mająli potomek, którego wartość ciągu zawieraModel substring - pozycjali element nie ma już znaczenia.

Zobacz teżTestowanie węzłów text () w stosunku do wartości ciągu w XPath
-5

Wklej mójcontains przykład tutaj:

//table[contains(@class, "EC_result")]/tbody
Nie matable element lubEC_result wartość klasy w kodzie OP.Ta odpowiedź nie ma tutaj sensu i powinna zostać usunięta. kjhughes

Powiązane pytania