XPath - Selecting elements that equal a value

developer picture developer · Jul 8, 2010 · Viewed 193.5k times · Source

In Xpath, I am wanting to select elements that equal a specific value.

Sample XML data:

<aaa id="11" >
    <aaa id="21" >
        <aaa id="31" ></aaa>
        <bbb id="32" >
            <aaa id="41" ></aaa>
            <bbb id="42" ></bbb>
            <ccc id="43" ></ccc>
            <ddd id="44" >qwerty</ddd>
            <ddd id="45" ></ddd>
            <ddd id="46" ></ddd>
        </bbb>
    </aaa>
    <bbb id="22" >
         <aaa id="33" >qwerty</aaa>
         <bbb id="34" ></bbb>
         <ccc id="35" ></ccc>
         <ddd id="36" ></ddd>
         <ddd id="37" ></ddd>
         <ddd id="38" ></ddd>
    </bbb>
    <ccc id="23" >qwerty</ccc>
    <ccc id="24" ></ccc>
 </aaa>

Now, using the XPath:

//ccc[.='qwerty']

I get the correct, expected results:

Name    Value
ccc     qwerty

Now, using the XPath:

//aaa[.='qwerty']

I get unexpected results:

Name    Value
aaa      
aaa     qwerty

And what I am particularly interested, is how to select any element with that value

XPath:

//*[.='qwerty']

I get very strange unexpected results:

Name    Value
aaa
bbb
ddd     qwerty
bbb     qwerty
aaa     qwerty
ccc     qwerty

Can someone explain these results, and how to fix my XPath expressions to get more expected results?

Answer

Dimitre Novatchev picture Dimitre Novatchev · Jul 8, 2010

The XPath spec. defines the string value of an element as the concatenation (in document order) of all of its text-node descendents.

This explains the "strange results".

"Better" results can be obtained using the expressions below:

//*[text() = 'qwerty']

The above selects every element in the document that has at least one text-node child with value 'qwerty'.

//*[text() = 'qwerty' and not(text()[2])]

The above selects every element in the document that has only one text-node child and its value is: 'qwerty'.