2
votes

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?

1

1 Answers

4
votes

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.