XPath: Dapatkan simpul orangtua dari simpul anak

157

Saya perlu mendapatkan simpul orangtua untuk simpul anak title 50

Saat ini saya hanya menggunakan

//*[title="50"]

Bagaimana saya bisa mendapatkan orang tuanya? Hasilnya harus berupa storesimpul.


<?xml version="1.0" encoding="utf-8"?>
<d:data xmlns:d="defiant-namespace" d:mi="23">
    <store d:mi="22">
        <book price="12.99" d:price="Number" d:mi="4">
            <title d:constr="String" d:mi="1">Sword of Honour</title>
            <category d:constr="String" d:mi="2">fiction</category>
            <author d:constr="String" d:mi="3">Evelyn Waugh</author>
        </book>
        <book price="8.99" d:price="Number" d:mi="9">
            <title d:constr="String" d:mi="5">Moby Dick</title>
            <category d:constr="String" d:mi="6">fiction</category>
            <author d:constr="String" d:mi="7">Herman Melville</author>
            <isbn d:constr="String" d:mi="8">0-553-21311-3</isbn>
        </book>
        <book price="8.95" d:price="Number" d:mi="13">
            <title d:constr="String" d:mi="10">50</title>
            <category d:constr="String" d:mi="11">reference</category>
            <author d:constr="String" d:mi="12">Nigel Rees</author>
        </book>
        <book price="22.99" d:price="Number" d:mi="18">
            <title d:constr="String" d:mi="14">The Lord of the Rings</title>
            <category d:constr="String" d:mi="15">fiction</category>
            <author d:constr="String" d:mi="16">J. R. R. Tolkien</author>
            <isbn d:constr="String" d:mi="17">0-395-19395-8</isbn>
        </book>
        <bicycle price="19.95" d:price="Number" d:mi="21">
            <brand d:constr="String" d:mi="19">Cannondale</brand>
            <color d:constr="String" d:mi="20">red</color>
        </bicycle>
    </store>
</d:data>
GibboK
sumber

Jawaban:

297

Gunakan parentsumbu dengan nama simpul orangtua.

//*[title="50"]/parent::store

XPath ini hanya akan memilih simpul induk jika itu adalah a store.

Tetapi Anda juga dapat menggunakan salah satunya

//*[title="50"]/parent::*
//*[title="50"]/..

Xpath ini akan memilih sembarang simpul induk. Jadi, jika dokumen berubah, Anda akan selalu memilih simpul, meskipun bukan simpul yang Anda harapkan.

EDIT

Apa yang terjadi dalam contoh yang diberikan di mana orang tua adalah sepeda tetapi orang tua dari orang tua adalah toko?

Apakah itu naik?

Tidak, itu hanya memilih toko jika itu adalah induk dari simpul yang cocok //*[title="50"].

Jika tidak, apakah ada metode untuk naik dalam kasus seperti itu dan mengembalikan Tidak ada jika tidak ada orang tua seperti itu?

Ya, Anda bisa menggunakan ancestorkapak

//*[title="50"]/ancestor::store

Ini akan memilih semua leluhur dari pencocokan simpul //*[title="50"]yang merupakan `toko. Misalnya

<data xmlns:d="defiant-namespace" d:mi="23">
    <store mi="1">
        <store mi="22">
            <book price="8.95" d:price="Number" d:mi="13">
                <title d:constr="String" d:mi="10">50</title>
                <category d:constr="String" d:mi="11">reference</category>
                <author d:constr="String" d:mi="12">Nigel Rees</author>
            </book>
        </store>
    </store>
</data>

Hasil seleksi XPath

René Link
sumber
7
Anda juga bisa menggunakan parent::*sintaks disingkat ..(misalnya: //*[title="50"]/..) atau predikat bersarang (contoh: //*[*[title="50"]])
Daniel Haley
1
Info tambahan: w3.org/TR/xpath/#axes dan w3.org/TR/xpath/#path-abbrev
Daniel Haley
3
Atau parent::node()yang sesuai dengan jalan pintas ..dan lebih baik menurut saya. Bahkan parent::*terbatas pada jenis simpul utama sumbu yang dalam banyak kasus tidak menjadi masalah.
Ludovic Kuty
3
Jika Anda menggunakan coba .xpath('..')atauxpath('parent::node()')
briankip
"XPath ini hanya akan memilih simpul induk jika itu adalah toko." - dan apa yang terjadi dalam contoh yang diberikan di mana induknya bicycletetapi induk dari induk itu store? Apakah itu naik? Jika tidak, apakah ada metode untuk naik dalam kasus seperti itu dan kembali Nonejika tidak ada orang tua seperti itu?
Martin Thoma
31

Sama seperti alternatif, Anda bisa menggunakannya ancestor.

//*[title="50"]/ancestor::store

Ini lebih kuat daripada parentkarena bisa mendapatkan kakek atau nenek buyut

Aminah Nuraini
sumber
20
Itu bukan "lebih kuat". Hanya berbeda. Jadi pilihan sumbu tergantung pada use case.
Ludovic Kuty
11

Anda dapat menggunakan dua titik di akhir ekspresi juga. Lihat contoh ini:

//*[title="50"]/..
phduarte
sumber
2

Baru, jawaban yang ditingkatkan untuk pertanyaan lama, yang sering diajukan ...

Bagaimana saya bisa mendapatkan orang tuanya? Hasilnya harus berupa storesimpul.

Gunakan predikat daripada sumbu parent::atauancestor::

Sebagian besar jawaban di sini pilih elemen titledan kemudian lintasi hingga elemen induk atau leluhur ( store) yang ditargetkan . Pendekatan yang lebih sederhana dan langsung adalah memilih elemen induk atau leluhur langsung di tempat pertama, meniadakan kebutuhan untuk melintasi ke parent::atau ancestor::sumbu:

//*[book/title = "50"]

Haruskah elemen intervensi bervariasi dalam nama:

//*[*/title = "50"]

Atau, dalam nama dan kedalaman:

//*[.//title = "50"]
kjhughes
sumber
Ini tidak menjawab pertanyaan. Penulis tidak harus mengetahui nama induk sebelumnya.
Kenn Sebesta
1
@KennSebesta: Saya telah memperbarui jawaban untuk mengatasi masalah Anda. Harap hapus downvote Anda jika keberatan Anda telah diatasi, atau beri tahu saya jika Anda merasa ada yang salah dengan jawabannya. Terima kasih.
kjhughes
0

Ini berfungsi dalam kasus saya. Saya harap Anda bisa mengekstrak makna darinya.

//div[text()='building1' and @class='wrap']/ancestor::tr/td/div/div[@class='x-grid-row-checker']
Shivam Bharadwaj
sumber