Syntax of the xml document:
Z
Z__2
Z__3
Instead of traversing back to the parent, just find the right parent to begin with:
//x will select all x elements.//x[//z] will select all x elements which have z elements as descendants.//x[//z]/@name will get the name attribute of each of those elements.I dont have a reputation, so I cannot add comment to accepted answer by Blender. But his answer will not work in general. Correct version is
//x[.//z]/@name
Explanation is simple - when you use filter like [//z] it will search for 'z' in global context, i.e. it returns true if xml contains at least one node z anywhere in xml. For example, it will select both names from xml below:
<root>
<x name="NOT-THIS">
</x>
<x name="GET-THIS">
<y>
<z>Z</z>
<z>Z__2</z>
<z>Z__3</z>
</y>
</x>
</root>
Filter [.//z] use context of current node (.) which is xand return only 2nd name.
You already have a good accepted answer, but here are some other helpful expressions:
//z/ancestor::x/@name - Find <z> elements anywhere, then find all the ancestor <x> elements, and then the name="…" attributes of them.
//z/../../@name - Find the <z> elements, and then find the parent node(s) of those, and then the parent node(s) of those, and then the name attribute(s) of the final set.
//z/parent::*/parent::*/@name, where the * means "an element with any name".The // is useful, but inefficient. If you know that the hierarchy is x/y/z, then it is more efficient to do something like //x[y/z]/@name