25

I am using XML and XQuerie. I usually use an XPath expression relative to a parent node to retrieve its child node. But, I am not sure how to do the opposite meaning if I have a child node, how do I retrieve its parent node.

<node id="50>
  <childnode1 childid="51" />
  <childnode2 childid="52" />
</node>

If I have the node <childnode1 childid="51" />, how do I retrieve its parent: <node id="50>

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
sony
  • 1,557
  • 10
  • 36
  • 50

4 Answers4

24

Short answer:

..

This selects the parent of the current (context) node.

Longer and more general answers:

//node()[childnode1/@childid="51"]

This selects any node in the document that has a child element named childnode1, that has an attibute childid, whose value is '51'.

One should try to avoid an expression that contains the // abbreviation, because this may be very inefficient. Use '//' only when the structure of the XML document isn't known in advance.

Best answer:

ExpressionSelectingTheChildNode/..
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
5

you use .. to get the parent, like this:

../childnode1

so if you have some XML document like this:

<a id="1">
  <b id="2">
    <c id="3">
      <d id="4"/>
    </c>
    <c id="5"/>
    <c id="6">
      <d id="7"/>
    </c>
  </b>
</a>

then the XQuery

//../d[@id = "4"]

would return the c node with id of 3.

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • Your expression means: *from all parents of decendant nodes (the same as all nodes having a child) a `d` child with `id` attribute equal to '4'*. So, it's not what the OP is asking... –  Sep 14 '10 at 21:04
2

Here is a more complex example of getting the parent node (..).

Q) Find all situations where one country's most popular language is another country's least popular, and both countries list more than one language. https://prod-c2g.s3.amazonaws.com/db/Winter2013/files/countries.xml

A)

for $b in doc("countries.xml")/countries/country/language
for $c in doc("countries.xml")/countries/country/language
where $b/../@name != $c/../@name 
and data($b) = data($c)
and count($b/../language) > 1
and count($c/../language) > 1
and $b/@percentage = max($b/../language/@percentage)
and $c/@percentage = min($c/../language/@percentage)
return 
  <LangPair language="{data($b)}">
     <MostPopular>{data($b/../@name)}</MostPopular>
     <LeastPopular>{data($c/../@name)}</LeastPopular>
    </LangPair>
Xavier John
  • 8,474
  • 3
  • 37
  • 51
0

Alternatively, you can also make use of fn:root() Xquery function.

bosari
  • 1,922
  • 1
  • 19
  • 38