The XPath 1.0 Specification states that ’td’ is the axis (e.g. children) and node-test (tag name TD) an everything inside the square brackets is a predicate-expression which is either evaluated as boolean (true or false) or in special-case of a number evaluated as positional filter of the node-set:
if the result is not a number, then the result will be converted as if by a call to the boolean function. Thus a location path para[3] is equivalent to para[position()=3].
Explained by Example
Following 3 XPath predicate cases are explained by evaluating on input from this sample table (w3schools):
+-------------------------------+-------------------+---------+
| Company | Contact | Country |
+-------------------------------+-------------------+---------+
| Alfreds Futterkiste | Maria Anders | Germany |
| Centro comercial Moctezuma | Francisco Chang | Mexico |
| Ernst Handel | Roland Mendel | Austria |
| Island Trading | Helen Bennett | UK |
| Laughing Bacchus Winecellars | Yoshi Tannamuri | Canada |
| Magazzini Alimentari Riuniti | Giovanni Rovelli | Italy |
+-------------------------------+-------------------+---------+
case 1: number as predicate
td[6]
selects the 6th child table-data element since number 6
is evaluated as shorthand for predicate position()=6
.
Example: select each cell of the the third column
XPath: //td[3]
Output:
<td>Germany</td>
<td>Mexico</td>
<td>Austria</td>
<td>UK</td>
<td>Canada</td>
<td>Italy</td>
Try online demo
case 2: quoted string as predicate
td['6']
selects every child table-data element since the string '6'
is not-empty or has non-zero length and thus evaluates to true
(see boolean-conversion). So node-set of TD-elements is not further filtered (because predicate is always true).
Example: select each cell (because the string-predicate is always true)
XPath: //td['3']
Output:
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
Try online demo
case 3: conditional predicate testing the elements
This is the real benefit of predicate expression and allows you to test on the elements, for example find all merged table-cells with colspan
attribute:
td[@colspan]
See this sophisticated use-case:
Xpath expression with multiple predicates
Example: select all cells where contents starts with 'A'
XPath: //tr/td[starts-with(., 'A')]
Output:
<td>Alfreds Futterkiste</td>
<td>Austria</td>
Try online demo