How to use XPath contains() here ?
Limitation of the contains() function had been encountered or other string function in XPath, for that purpose use below,
//ul[@class='featureList' and contains(li, 'Model')]
The first argument should be a string. If the user grain it a node list giving it “li” do that, a conversion to string should take place. This conversion done for the first node in the list.
In some case, the first node in the list is <li><b>Type:</b> Clip Fan</li> converted to a string: “Type: Clip Fan” which termed like below,would select a node,
//ul[@class='featureList' and contains(li, 'Type')]
contains() termed as containing a substring and not contains a node.
XPath is often distort,
Bad analyse: Select those ul elements which contain an li element with Model in it.
This is worse because
- contains(x,y) expects x to be a string, and
- the XPath rule for converting multiple elements to a string is this:
This converted node-set to a string by returning the string-value of the node in the node-set that is first in document order. An empty string is returned if the node-set is empty.
Good analyse: Select those ul elements whose first li child has a string-value that contains a Model substring.
<r> <ul id="one"> <li>Model A</li> <li>Foo</li> </ul> <ul id="two"> <li>Foo</li> <li>Model A</li> </ul> </r>
- //ul[contains(li, ‘Model’)] selects the one ul element.
The two ul element is not selected because the string-value of the first li child of the two ul is Foo, which will not contain the Model substring.
- //ul[li[contains(.,’Model’)]] selects the one and two ul elements.
Both ul elements are selected because contains() is applied to all li. So, the multiple-element-to-string conversion rule is avoided. Both ul elements have an li child whose string value contains the Model substring — position of the li element no longer.