Search code examples
xmlxpathxpath-2.0

Using XPath is it possible to get the name of each node in a path to a target node as a String?


Using XPath is it possible to get the name of each node in a path to a target node as a String?

Example.xml

<parent>
    <childOne>
        <target>true</target>
    </childOne>

    <childTwo>
        <target>true</target>
    </childTwo>

    <childThree>
        <target>false</target>
    </childThree>
</parent>

Selects all ancestors where target is true

//node()[target = "true"]/ancestor-or-self::*

Is it possible to get this result

"parent/childOne/target"

"parent/childTwo/target"


Solution

  • How about this XPath 2.0 expression:

    string-join(for $node in //node()[text() = 'true'] return string-join(for $ancestor in $node/ancestor-or-self::* return concat('/',local-name($ancestor)), ''), '&#10;')
    

    This will return the path strings seperated by newline characters. If you want seperate result nodes for each path you may want to use

    for $node in //node()[text() = 'true'] return string-join(for $ancestor in $node/ancestor-or-self::* return concat('/',local-name($ancestor)), '')
    

    instead.

    Note that I had to change target = 'true' into text() = 'true' to include the tags at the lowest level.

    The trick with the concatenation of the partial path strings was inspired by this answer: Concatenate multiple node values in xpath