Reputation: 409
I have an XML document, and I need to locate the nearest descendant (physically closest in the tree - "treasure" in the example) to my previous-sibling. I don't know any element names, element contents, nor how deep the current node or the node I want to select are in the document. An example follows:
<tagA>
<tagB>
<tagC>
junk
</tagC>
<tagC>
<tagD>
junk
</tagD>
</tagC>
</tagB>
<tagB>
<tagC>
treasure
</tagC>
</tagB>
</tagA>
<tagX/>
From the position of tagX, I need to be able to test if my preceding sibling has descendants and select the closest one, "Treasure".
I'm guessing I can use descendant::*[last()]
once I have the preceding sibling selected, but I'm not sure of the syntax to get there. Obviously previous-sibling::descendant::*[last()]
won't work.
Is there a way to combine these axes to achieve this in a single query?
Upvotes: 2
Views: 1220
Reputation: 29042
You had only minor mistakes in your XPath expression.
Try the following expression from the context node <tagX>
.
preceding-sibling::*[1]/descendant::*[last()]
Its output is
<tagC>
treasure
</tagC>
If you only need the text content, append /text()
to the expression.
An alternative expression is
(preceding-sibling::*[1]//text()[normalize-space()])[last()]/..
The output using the sample XML is the same.
You have to decide which solution does better fit your needs.
Upvotes: 6