I need get the parent node for child node title 50
At the moment I am using only
//*[title="50"]How could I get its parent?
Result should be the 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> 4 Answers
Use the parent axes with the parent node's name.
//*[title="50"]/parent::storeThis 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. So if the document changes you will always select a node, even if it is not the node you expect.
EDIT
What happens in the given example where the parent is a bicycle but the parent of the parent is a store?
Does it ascent?
No, it only selects the store if it is a parent of the node that matches //*[title="50"].
If not, is there a method to ascent in such cases and return None if there is no such parent?
Yes, you can use ancestor axes
//*[title="50"]/ancestor::storeThis will select all ancestors of the node matching //*[title="50"] that are ` stores. 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> 7 Just as an alternative, you can use ancestor.
//*[title="50"]/ancestor::storeIt's more powerful than parent since it can get even the grandparent or great great grandparent
You can use the two dots at the end of expression, too. See this example:
//*[title="50"]/.. New, improved answer to an old, frequently asked question...
How could I get its parent? Result should be the
storenode.
Use a predicate rather than the parent:: or ancestor:: axis
Most answers here select the title and then traverse up to the targeted parent or ancestor (store) element. A simpler, direct approach is to select parent or ancestor element directly in the first place, obviating the need to traverse to a parent:: or ancestor:: axes:
//*[book/title = "50"]Should the intervening elements vary in name:
//*[*/title = "50"]Or, in name and depth:
//*[.//title = "50"] 0