views:

410

answers:

1

With my current node selected I wish to find an element <name> [./name] and return the text content. If an element <name> does not exist in the currently selected node I wish to check the parent element [./parent::name] and so on recursively up to the root, returning the value of the nearest parent where the element exists.

Can it be done with XPath?

+2  A: 

(Edit: I misinterpreted the question the first time)

I propose to use

ancestor-or-self::name[1]

This finds all name elements, starting with self, parent, and so on, and orders them in increasing distance from self. So selecting [1] gives you the nearest one.

Martin v. Löwis
I believe it's `ancestor-or-self::name[1]` (since he suggested `parent::name`).
Tomalak
Ah, thanks - I have rewritten my response to match the question.
Martin v. Löwis
Based on your original response I used ancestor-or-self::*[name][1]/name. Is there a difference and which is preferred?
Daniel Skinner
There is a difference: your form might select multiple name elements. E.g. if you look for table elements in HTML, it would give you all sibling tables for your ancestor table, which is not exactly what you want (IIUC). In addition, in XPath, it is usually better to use the smaller term, and eliminate all redundant expressions. Not only will this speed up evaluation, but it will also make the expression more understandable - as XPath *is* very difficult both to write, and to read.
Martin v. Löwis
I can't get this to return any matches where `ancestor-or-self::*[name][1]/name` produces the desired result (negating the consequences you mentioned)
Daniel Skinner
`ancestor-or-self::*/SURNAME[1]` seems to work. Does this expression present any issues of it's own?
Daniel Skinner
If this works, and ancestor-or-self::SURNAME doesn't, then SURNAME *isn't* an ancestor. Is that right? The problem with your current expression is that it gives you all first SURNAME children of any ancestor. So if you have multiple ancestors which have SURNAME children, you still may get multiple results.
Martin v. Löwis
Ah, I understand how the expression works now. This is the desired behaviour and there are never multiple SURNAME elements. SURNAME is always a child element of the ancestor-or-self axis.
Daniel Skinner