XPath: Übergeordneten Knoten vom untergeordneten Knoten abrufen

157

Ich brauche den übergeordneten Knoten für den untergeordneten Knoten title 50

Im Moment benutze ich nur

//*[title="50"]

Wie könnte ich seine Eltern bekommen? Ergebnis sollte der storeKnoten sein.


<?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
quelle

Antworten:

294

Verwenden Sie die parentAchsen mit dem Namen des übergeordneten Knotens.

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

Dieser XPath wählt den übergeordneten Knoten nur aus, wenn es sich um einen handelt store.

Sie können aber auch eine davon verwenden

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

Diese xpaths wählen einen beliebigen übergeordneten Knoten aus. Wenn sich das Dokument ändert, wählen Sie immer einen Knoten aus, auch wenn es nicht der Knoten ist, den Sie erwarten.

BEARBEITEN

Was passiert in dem gegebenen Beispiel, in dem der Elternteil ein Fahrrad ist, der Elternteil des Elternteils jedoch ein Geschäft?

Steigt es auf?

Nein, der Speicher wird nur ausgewählt, wenn er ein übergeordneter Knoten des übereinstimmenden Knotens ist //*[title="50"].

Wenn nicht, gibt es in solchen Fällen eine Methode, um aufzusteigen und None zurückzugeben, wenn es keinen solchen Elternteil gibt?

Ja, Sie können ancestorAchsen verwenden

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

Dadurch werden alle Vorfahren des Knotenabgleichs ausgewählt //*[title="50"], die `Speicher sind. Z.B

<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>

XPath-Auswahlergebnis

René Link
quelle
7
Sie könnten auch die Verwendung parent::*abgekürzte Syntax ..(Beispiel: //*[title="50"]/..) oder eine verschachtelte Prädikat (Beispiel: //*[*[title="50"]])
Daniel Haley
1
Zusätzliche Informationen: w3.org/TR/xpath/#axes und w3.org/TR/xpath/#path-abbrev
Daniel Haley
3
Oder parent::node()was der Abkürzung entspricht ..und meiner Meinung nach besser ist. Tatsächlich parent::*ist es auf den Hauptknotentyp der Achse beschränkt, was in den meisten Fällen kein Problem darstellt.
Ludovic Kuty
3
Wenn Sie versuchen, versuchen .xpath('..')oderxpath('parent::node()')
briankip
"Dieser XPath wählt den übergeordneten Knoten nur aus, wenn es sich um ein Geschäft handelt." - und was passiert in dem gegebenen Beispiel, in dem der Elternteil bicycleaber der Elternteil des Elternteils ist store? Steigt es auf? Wenn nicht, gibt es in solchen Fällen eine Methode zum Aufstieg und zur Rückkehr, Nonewenn es keinen solchen Elternteil gibt?
Martin Thoma
31

Nur als Alternative können Sie verwenden ancestor.

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

Es ist mächtiger als parentda es sogar die Großeltern oder Ururgroßeltern bekommen kann

Aminah Nuraini
quelle
20
Es ist nicht "mächtiger". Es ist einfach anders. Somit hängt die Wahl der Achse vom Anwendungsfall ab.
Ludovic Kuty
11

Sie können auch die beiden Punkte am Ende des Ausdrucks verwenden. Siehe dieses Beispiel:

//*[title="50"]/..
Phduarte
quelle
2

Neue, verbesserte Antwort auf eine alte, häufig gestellte Frage ...

Wie könnte ich seine Eltern bekommen? Ergebnis sollte der storeKnoten sein.

Verwenden Sie ein Prädikat anstelle der Achse parent::oderancestor::

Bei den meisten Antworten wird hier das Element ausgewählt titleund anschließend zum Zielelement für Eltern oder Vorfahren ( store) weitergeleitet. Ein einfacherer, direkter Ansatz besteht darin, das übergeordnete Element oder das Vorfahrselement direkt auszuwählen, ohne dass eine parent::oder mehrere ancestor::Achsen durchlaufen werden müssen :

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

Sollten die dazwischenliegenden Elemente im Namen variieren:

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

Oder in Name und Tiefe:

//*[.//title = "50"]
kjhughes
quelle
Dies beantwortet die Frage nicht. Der Autor kennt den übergeordneten Namen nicht unbedingt im Voraus.
Kenn Sebesta
1
@KennSebesta: Ich habe die Antwort aktualisiert, um Ihr Anliegen anzusprechen. Bitte entfernen Sie Ihre Ablehnung, wenn Ihr Einspruch angesprochen wurde, oder lassen Sie mich wissen, wenn Sie der Meinung sind, dass mit der Antwort etwas nicht stimmt. Vielen Dank.
kjhughes
0

Das funktioniert in meinem Fall. Ich hoffe, Sie können daraus einen Sinn ziehen.

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