XPath: get parent node from child node

I need to get the parent node for the child node "title 50"

I am currently using only

//*[title="50"] 

How can I get my parent? The result should be a 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">JRR 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> 
+123
xml xpath
Jan 30 '15 at 14:10
source share
5 answers

Use the parent axis with the name of the parent node.

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

This XPath will only select the parent node if it is a store .

But you can also use one of these

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

These xpaths will select any parent node. Therefore, if the document changes, you will always select the node, even if it is not the node that you expect.

EDIT

What happens in this example where the parent is the bike and the parent is the store?

Is it climbing?

No, he chooses the repository only if he is the parent of the node that matches //*[title="50"] .

If not, is there a way to rise in such cases and return None if there is no such parent?

Yes you can use ancestor axes

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

This will select all the ancestors of the corresponding node //*[title="50"] , which are 'repositories. E.G.

 <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

+241
Jan 30 '15 at 14:14
source share

Alternatively, you can use ancestor .

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

It is more powerful than parent , as it can even get grandfather or great-grandfather.

+22
Mar 15 '17 at 10:12
source share

You can also use two dots at the end of an expression. Check out this example:

 //*[title="50"]/.. 
+9
Jun 29 '18 at 14:11
source share

This works in my case. I hope you can make sense of it.

 //div[text()='building1' and @class='wrap']/ancestor::tr/td/div/div[@class='x-grid-row-checker'] 
0
Apr 17 '18 at 6:53
source share

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

How could I get his parent? The result should be a store node.

Use the predicate, not the parent:: or ancestor:: axis

Most of the answers here select title and then move on to the store target. A simpler, more direct approach is to first select the store element directly, which eliminates the need to go to parent:: or ancestor::

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

If intermediate elements differ in name:

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

Or by name and by depth:

 //store[.//title = "50"] 
0
Sep 23 '19 at 14:52
source share



All Articles