tags:

views:

30

answers:

1

Is there any way to retrieve all elements of specific hierarchy level using XPath?

Upd.

<A>
   <B>1</B>
   <B>2</B>
</A>
<C>
   <D>3</D>
   <D>4</D>
</C>

I need to retrieve all B and D elements (hierarchy level = 2)

+4  A: 

Your example lacks a root element, so I assume something like this:

<ROOT>
  <A>
    <B>1</B>
    <B>2</B>
  </A>
  <C>
    <D>3</D>
    <D>4</D>
  </C>
</ROOT>

With this, a simple version would be to just use the appropriate number of 'any element' wildcards to get your result:

xpath = '/*/*/*'

(Meaning 'select any child element of any child element of any root element')

Alternatively, if you want to express the level numerically, you could use:

xpath = '//*[count(ancestor::*) = 2]'

(Meaning 'select any element with 2 ancestors')


Edit/Note: As Dimitre Novatchev correctly pointed out, it is important to differentiate between nodes and elements, and I fixed my answer accordingly. (While elements are nodes themselves, there are also six other types of nodes!)

The difference can be illustrated with the given example by altering the ancestor based xpath slightly to:

xpath = '//*[count(ancestor::node())=2]'

This would select A and B, as the root element would count as one ancestor node, and the root node '/' as another!

Henrik Opel
While this answer is correct, there are certain terminological issues. In XPath "node" is something generally different from "element". In particular, the `root node`, selected by the XPath expression `/` is *not* an element. Also, besides element children an element can have children of type: text node, comment and processing instruction. Please, correct the statements in your answer referring to "node" to refer to "element".
Dimitre Novatchev
@Dimitre Novatchev: Oups, You're right, of course - thanks for pointing this out. I adjusted the answer accordingly (and added a demonstration of the difference as a bonus ;)
Henrik Opel
@Dimitre Novatchev: BTW, given your rep count, why not just fix errors like this yourself directly?
Henrik Opel
[why not just fix errors like this yourself directly?] Because I only have time to downvote ... :) In this case this was a minor issue in your answer, so a downvote would be unfair.Now you have a +1 from me.
Dimitre Novatchev