XPath and tricky nested nodes
xml, xpath, xslt
Solution
I. This short and simple XPath 1.0 expression:
//*[not(../*/*)]
when evaluated against the provided XML document:
<Type>
<ID></ID>
<Name></Name>
<Child>
<Type>
<ID></ID>
<Name></Name>
<Child>
<Type>
<ID></ID>
<Name></Name>
<Child>
<Type>
<ID></ID>
<Name></Name>
<Child>
<Type>
<ID></ID>
<Name>FIND ME</Name>
</Type>
</Child>
</Type>
</Child>
</Type>
</Child>
</Type>
</Child>
</Type>
selects these two elements:
<ID/>
<Name>FIND ME</Name>
Therefore, in your case one XPath expression that produces the wanted result is:
//*[not(../*/*)]/Name
II. Generic XPath 1.0 expression that selects the elements with maximum depth when it is known that the maximum depth isn't greater than a given number:
//*[count(ancestor::*) >= 9]
|
//*[not(//*[count(ancestor::*) >= 9])]
[count(ancestor::*) = 8]
|
//*[not(//*[count(ancestor::*) >= 8])]
[count(ancestor::*) = 7]
|
//*[not(//*[count(ancestor::*) >= 7])]
[count(ancestor::*) = 6]
|
//*[not(//*[count(ancestor::*) >= 6])]
[count(ancestor::*) = 5]
|
//*[not(//*[count(ancestor::*) >= 5])]
[count(ancestor::*) = 4]
|
//*[not(//*[count(ancestor::*) >= 4])]
[count(ancestor::*) = 3]
|
//*[not(//*[count(ancestor::*) >= 3])]
[count(ancestor::*) = 2]
|
//*[not(//*[count(ancestor::*) >= 2])]
[count(ancestor::*) = 1]
|
/*[not(//*[count(ancestor::*) >= 1])]
While this seems a very long and unwieldy, an XML document typically is not more than 4-5 level deep and such expression is actually practical.
III. Generic XPath 2.0 solution:
//*[not(*) and count(ancestor::*) = max(//*/count(ancestor::*))]
Problem
Given the following tricky XML: ``` <Type> <ID></ID> <Name></Name> <Child> <Type> <ID></ID> <Name></Name> <Child> <Type> <ID></ID> <Name></Name> <Child> <Type> <ID></ID> <Name></Name> <Child> <Type> <ID></ID> <Name>FIND ME</Name> </Type> </Child> </Type> </Child> </Type> </Child> </Type> </Child> </Type> ``` Is it possible to obtains the deepest Type's Name field? I've tried constructions like that: ``` //*not(*) ``` but with no results..