Jason Witherspoon
Jason Witherspoon

Reputation: 63

Xpath text contains puzzlement

Given the following html:

<span class="fum foe"> <b>45</b> results </span>

...can anyone tell me why the following xpath is not finding it?

//span[contains(text(), "results")]

I've attempted some "normalize-space" mojo, but haven't been able to get anything to work. Went with a "fum foe" workaround but trying to understand what I'm not understanding.

Many thanks in advance!

Upvotes: 2

Views: 42

Answers (2)

Gilles Qu&#233;not
Gilles Qu&#233;not

Reputation: 185530

This doesn't match because of the 'b' tag.

This one works:

//span[contains(., "results")]

. is a multiple node text search.

Learn about the dot.

And the explanation by one of XPath dad, thanks Mr Kay

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163458

In XPath 1.0, when a function like contains() expects a string as its first argument, and you supply a node-set containing multiple nodes (text() in your example), the node-set is converted to a string by ignoring all nodes except the first.

This elephant trap was removed in XPath 2.0, which makes this situation an error. In both versions, you can test whether any of the text nodes contains "results" using

//span[text()[contains(., "results")]]

But you would probably be quite happy to select the element if the word "contains" is split across multiple text nodes, in which case the correct query (again, in both versions) is

//span[contains(., "results")]

Use of text() in XPath expressions is very often a code smell.

Upvotes: 1

Related Questions