Подтвердить что ты не робот

XPath: получить родительский node из дочернего node

Мне нужно получить родительский node для дочернего node "title 50"

В данный момент я использую только

//*[title="50"]

Как я могу получить своего родителя? Результат должен быть store node.


<?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>
4b9b3361

Ответ 1

Используйте оси parent с именем родительского узла.

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

Этот XPath будет выбирать родительский узел только в том случае, если это store.

Но вы также можете использовать один из этих

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

Эти xpaths выберут любой родительский узел. Поэтому, если документ изменяется, вы всегда будете выбирать узел, даже если это не тот узел, который вы ожидаете.

EDIT

Что происходит в данном примере, где родитель - это велосипед, а родитель - это магазин?

Это восхождение?

Нет, он выбирает хранилище только в том случае, если он является родителем узла, который соответствует //*[title="50"].

Если нет, есть ли способ подняться в таких случаях и вернуть None, если такого родителя нет?

Да, вы можете использовать оси ancestor

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

Это выберет всех предков соответствующего узла //*[title="50"], которые являются 'хранилищами. Э.Г.

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

Ответ 2

Как альтернатива, вы можете использовать ancestor.

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

Он более мощный, чем parent, так как он может получить даже дедушку или прадедушку.

Ответ 3

Вы также можете использовать две точки в конце выражения. Посмотрите этот пример:

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

Ответ 4

Это работает в моем случае. Я надеюсь, что вы сможете извлечь из этого смысл.

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

Ответ 5

New, improved answer to an old, frequently asked question...

Как я мог получить его родителя? Результатом должен быть узел store.

Используйте предикат, а не ось parent:: или ancestor::

Большинство ответов здесь выбирают title и затем переходят к целевому элементу store. Более простой, прямой подход заключается в том, чтобы сначала выбрать элемент store непосредственно, что устраняет необходимость перехода к parent:: или ancestor:::

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

Если промежуточные элементы различаются по названию:

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

Или по названию и по глубине:

//store[.//title = "50"]