Apa XPath yang benar untuk memilih atribut yang mengandung "foo"?

176

Dengan XML ini, XPath mengembalikan semua elemen yang propatributnya berisi Foo(tiga node pertama):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>
ripper234
sumber
1
Mengapa semua orang melihat atribut "prop"? Apakah saya melewatkan sesuatu? Itu hanya mengatakan dapatkan tiga node pertama.
6
Semua orang melihat atribut prop karena itu yang diminta. Dapatkan semua simpul di mana prop berisi "Foo". Tambahkan <a prop="Foo5" /> dan Anda akan melihat mengapa itu bukan hanya "tiga node pertama" ..
erlando
Pertanyaan di dalam tubuh adalah kata-kata yang buruk, terlepas dari judulnya. Bisakah foo benar-benar berada dalam atribut prop, atau apakah Anda serius hanya ingin tiga node pertama?
3
Ya, silakan merujuk ke judulnya (dan silakan diedit).
ripper234
Jika Anda membutuhkan perbandingan case-insensitive lihat find-an-element-atribut-atribut-mengandung-a-text-case-insensitive
Michael Freidgeim

Jawaban:

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

Bekerja jika saya menggunakan XML ini untuk mendapatkan hasil kembali.

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

Sunting: Hal lain yang perlu diperhatikan adalah bahwa sementara XPath di atas akan mengembalikan jawaban yang benar untuk xml tertentu, jika Anda ingin menjamin Anda hanya mendapatkan "a" elemen dalam elemen "bla", Anda harus seperti yang disebutkan orang lain juga menggunakan

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

Ini akan mencari Anda semua "a" elemen di seluruh dokumen xml Anda, terlepas dari yang bersarang di elemen "bla"

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

Saya menambahkan ini demi ketelitian dan semangat stackoverflow. :)

orang jahat
sumber
3
xmlme.comsekarang dialihkan ke beberapa host lain dan tampaknya tidak meng-host alat atau yang sejenisnya.
jpmc26
26

XPath ini akan memberi Anda semua node yang memiliki atribut yang mengandung 'Foo' terlepas dari nama simpul atau nama atribut:

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

Tentu saja, jika Anda lebih tertarik pada isi dari atribut itu sendiri, dan belum tentu simpul induknya, cukup taruh / ..

//attribute::*[contains(., 'Foo')]
Alex Beynenson
sumber
2
Untuk semua node//@*[contains(., 'Foo')]
aliopi
16
descendant-or-self::*[contains(@prop,'Foo')]

Atau:

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

Atau:

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

Dibedah:

descendant-or-self::

Sumbu - cari melalui setiap simpul di bawahnya dan simpul itu sendiri. Sering kali lebih baik mengatakan ini daripada //. Saya telah menemui beberapa implementasi di mana // berarti di mana saja (decendant atau self of the root node). Yang lainnya menggunakan sumbu default.

* or /bla/a

Tag - pencocokan wildcard, dan / bla / a adalah jalur absolut.

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

Kondisi dalam []. @prop adalah singkatan untuk atribut :: prop, karena atribut adalah sumbu pencarian lain. Atau Anda dapat memilih 3 pertama dengan menggunakan fungsi posisi ().

1729
sumber
6

John C adalah yang terdekat, tetapi XPath peka huruf besar-kecil, jadi XPath yang benar adalah:

/bla/a[contains(@prop, 'Foo')]
Metro Smurf
sumber
4

Sudahkah Anda mencoba sesuatu seperti:

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

Saya tidak pernah menggunakan fungsi berisi sebelumnya tetapi menduga itu harus berfungsi seperti yang diiklankan ...

toddk
sumber
@toddk ... Anda menargetkan atribut yang tidak ada: @foo. Anda ingin menargetkan @prop ;-)
Metro Smurf
4

Jika Anda juga harus mencocokkan konten tautan itu sendiri, gunakan teks ():

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

SomeDudeSomewhere
sumber
2

/ bla / a [berisi (@prop, "foo")]

David Hill
sumber
1

Untuk kode di atas ... // * [berisi (@ prop, 'foo')]

digiguru
sumber
ini untuk elemen apa pun dengan foo in, tetapi atributnya harus "prop"
digiguru
1

coba ini:

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

yang seharusnya berfungsi untuk tag "a" apa pun dalam dokumen

Dani Duran
sumber