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>
Ответы
Ответ 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"]