Jaka jest poprawna ścieżka XPath do wybierania atrybutów zawierających „foo”?


176

Biorąc pod uwagę ten kod XML, to, co XPath zwraca wszystkie elementy, których propatrybut zawiera Foo(pierwsze trzy węzły):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>

1
Dlaczego wszyscy patrzą na atrybut „prop”? Przegapiłem coś? Mówi tylko, że pobierz pierwsze trzy węzły.

6
Wszyscy patrzą na atrybut rekwizytu, ponieważ o to pytano. Pobierz wszystkie węzły, w których prop zawiera „Foo”. Dodaj <a prop="Foo5" />, a zobaczysz, dlaczego nie chodzi tylko o „pierwsze trzy węzły”…
erlando,

Pytanie w treści jest słabo sformułowane, niezależnie od tytułu. Czy foo naprawdę może znajdować się w dowolnym atrybucie właściwości, czy naprawdę chcesz tylko pierwszych trzech węzłów?

3
Tak, zapoznaj się z tytułem (i nie krępuj się edytować).
ripper234

Jeśli potrzebujesz wielkości liter porównania Zobacz Find-an-element, którego atrybut-zawiera-a-text-case-insensitively
Michael Freidgeim

Odpowiedzi:


307
//a[contains(@prop,'Foo')]

Działa, jeśli użyję tego XML do odzyskania wyników.

<bla>
 <a prop="Foo1">a</a>
 <a prop="Foo2">b</a>
 <a prop="3Foo">c</a>
 <a prop="Bar">a</a>
</bla>

Edycja: Inną rzeczą wartą uwagi jest to, że chociaż XPath powyżej zwróci poprawną odpowiedź dla tego konkretnego xml, jeśli chcesz zagwarantować, że otrzymasz tylko elementy "a" w elemencie "bla", powinieneś, tak jak inni wspominali, również użyć

/bla/a[contains(@prop,'Foo')]

Spowoduje to przeszukanie wszystkich elementów „a” w całym dokumencie xml, niezależnie od tego, czy są one zagnieżdżone w elemencie „blah”

//a[contains(@prop,'Foo')]  

Dodałem to ze względu na dokładność i w duchu przepełnienia stosu. :)


3
xmlme.comteraz przekierowuje do innego hosta i nie wydaje się hostować narzędzia ani niczego podobnego.
jpmc26

26

Ta XPath da ci wszystkie węzły, które mają atrybuty zawierające „Foo”, niezależnie od nazwy węzła lub nazwy atrybutu:

//attribute::*[contains(., 'Foo')]/..

Oczywiście, jeśli bardziej interesuje Cię zawartość samego atrybutu, a niekoniecznie jego węzeł nadrzędny, po prostu upuść / ..

//attribute::*[contains(., 'Foo')]

2
Dla wszystkich węzłów//@*[contains(., 'Foo')]
aliopi

16
descendant-or-self::*[contains(@prop,'Foo')]

Lub:

/bla/a[contains(@prop,'Foo')]

Lub:

/bla/a[position() <= 3]

Rozcięto:

descendant-or-self::

Oś - przeszukaj każdy węzeł pod spodem i sam węzeł. Często lepiej to powiedzieć niż //. Spotkałem kilka implementacji, w których // oznacza gdziekolwiek (decendant lub self z węzła głównego). Inne używają domyślnej osi.

* or /bla/a

Tag - dopasowanie wieloznaczne, a / bla / a to ścieżka bezwzględna.

[contains(@prop,'Foo')] or [position() <= 3]

Stan w []. @prop jest skrótem od attribute :: prop, ponieważ atrybut to kolejna oś wyszukiwania. Alternatywnie możesz wybrać pierwsze 3 za pomocą funkcji position ().


6

John C jest najbliższy, ale XPath rozróżnia wielkość liter, więc poprawna XPath to:

/bla/a[contains(@prop, 'Foo')]

4

Czy próbowałeś czegoś takiego:

// a [zawiera (@prop, "Foo")]

Nigdy wcześniej nie korzystałem z funkcji zawiera, ale podejrzewam, że powinna działać zgodnie z reklamą ...


@toddk ... celujesz w nieistniejący atrybut: @foo. Chciałbyś celować w @prop ;-)
Metro Smurf,

4

Jeśli chcesz również dopasować treść samego linku, użyj text ():

//a[contains(@href,"/some_link")][text()="Click here"]



1

Dla powyższego kodu ... // * [zawiera (@ prop, 'foo')]


dotyczy to dowolnego elementu z foo in, ale atrybut musi mieć wartość „prop”
digiguru

1

Spróbuj tego:

// a [zawiera (@ prop, 'foo')]

to powinno działać dla wszystkich znaczników „a” w dokumencie

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.