Bagaimana cara memilih node menggunakan XPath jika node saudara memiliki nilai tertentu?


89

Saya memiliki dokumen berikut:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

Bagaimana saya bisa mendapatkan nilai <cc>menggunakan XPath jika <bb>ada zz?


1
Masalahnya adalah saya tahu cara mengakses node tertentu, tetapi saya tidak tahu mengakses node jika saudara kandung memiliki nilai tertentu. Bisakah itu menjadi sesuatu seperti ini / a / cc / contains (/ a / bb = 'zz')?
HOE SENGKIANG

Jawaban:


101

Tidak yakin mengapa semua orang menanyakan saudara kandung, Anda juga dapat memeriksa <bb/>-elements yang cocok dengan predikat dari <a/>predikat:

//a[bb/text() = "zz"]/cc/text()

24
"Tidak yakin mengapa semua orang menanyakan tentang saudara kandung" : Mungkin karena pertanyaannya untuk saudara kandung .. ;-)
hr_117

4
Sepertinya saya sebenarnya tidak membaca judulnya. :) Jawaban tetap valid.
Jens Erat

2
Pertanyaan jawaban Anda untuk saudara kandung juga. Anda hanya tidak menggunakan *-siblingsumbu. +1 sekalipun.
LarsH

Ini tidak menjawab pertanyaan tetapi menjawab pertanyaan saya yang sebenarnya yang saya rumuskan dengan buruk. Terima kasih!
Pengguna9213


23

T: Bagaimana cara memilih node menggunakan XPath jika node saudara memiliki nilai tertentu?
Karena hanya ada "Sumbu XPath" untuk saudara berikut dan saudara sebelumnya, Anda dapat menggunakan salah satu dari mereka jika posisinya ditetapkan.

Tetapi lebih baik: Carilah jika ccorang tua memiliki anak bbdengan nilai 'zz':

//cc[../bb='zz']

6
Baik itu atau //a[bb = 'zz']/cc.
Tomalak

Tidak yakin apa yang Anda maksud dengan 'hanya "XPath Axes" untuk saudara-saudara berikut dan saudara-saudara sebelumnya'. Apakah Anda mengacu pada fakta bahwa tidak ada satu sumbu untuk semua saudara kandung?
LarsH

@ LarsH: Ya maaf, (maafkan bahasa Inggris saya yang buruk :-() - itulah yang ingin saya katakan. (Karena pertanyaannya untuk saudara kandung.)
hr_117

6

Pertama, contoh Anda bukanlah XML dengan format yang baik. Melihat itu dan bahwa Anda tidak menggambarkan maksud Anda dengan baik (Apa sebenarnya yang ingin Anda pilih dalam kondisi apa?), Saya berasumsi Anda ingin melakukan ini:

//cc[preceding-sibling::bb[text()="zz"]]/text()

Itu memilih

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

Anda bisa menulis juga sebagai

//bb[text()="zz"]/following-sibling::cc/text()

Silakan lihat spesifikasinya , ini memiliki beberapa contoh yang dapat dibaca dengan sangat baik dari mana Anda akan belajar banyak.


1
@ LarsH Terima kasih atas koreksi dari "tidak valid" menjadi "tidak terbentuk dengan baik". Saya belajar sesuatu yang baru hari ini.
Petr Janeček

4
//a/cc[../bb='zz']/text()

// a: Memilih semua elemen 'a' dimanapun itu.

// a / cc: Memilih elemen 'cc' yang merupakan turunan dari elemen 'a' (di mana pun a berada).

..: Memilih induk dari node saat ini.

[../bb='zz ']: dimana nilai dari elemen sibling' bb 'adalah zz.

Referensi: http://www.w3schools.com/xsl/xpath_syntax.asp


4

Solusi lain untuk masalah ini adalah

//bb[contains(.,'zz')]/../cc/text()

Penjelasan : Setiap bbyang berisi 'zz'string di semua node anak bbkemudian pergi ke node induk yang bbmenggunakan .., sekarang kita dapat mengakses ccteks yang kembali.

Saya harap penjelasan itu tidak rumit.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.