问题
Syntax of the xml document:
<x name="GET-THIS">
<y>
<z>Z</z>
<z>Z__2</z>
<z>Z__3</z>
</y>
</x>
I'm able to get all z elements using:
xpath("//z")
But after that I got stuck, I'm not sure what to do next. I don't really understand the syntax of the ..
parent method
So, how do I get the attribute of the parent of the parent of the element?
回答1:
Instead of traversing back to the parent, just find the right parent to begin with:
//x
will select allx
elements.//x[//z]
will select allx
elements which havez
elements as descendants.//x[//z]/@name
will get thename
attribute of each of those elements.
回答2:
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 thename="…"
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 thename
attribute(s) of the final set.- This is the same as:
//z/parent::*/parent::*/@name
, where the*
means "an element with any name".
- This is the same as:
The
//
is useful, but inefficient. If you know that the hierarchy isx/y/z
, then it is more efficient to do something like//x[y/z]/@name
回答3:
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 x
and return only 2nd name.
来源:https://stackoverflow.com/questions/16950608/xpath-parent-attribute-of-selection