I can't clearly understand the differences between using //element
and /descendant::element
when selecting multiple children of a base element in XPath.
Given this HTML snippet
<html>
<body>
<div class="popupContent">
<table>
<tr class="aclass"><td> Hello </td> <td> <input type="text" value="FIRST" /> </td></tr>
<tr class="aclass"><td> Goodbye </td> <td> <input type="text" value="SECOND" /> </td></tr>
</table>
</div>
</body>
</html>
I need to select each input
based on its positioning in the table.
//div[@class='popupContent']//input[1]
this selects the first input
//div[@class='popupContent']//input[2]
this gives error
//div[@class='popupContent']/descendant::input[1]
this again selects the first input
//div[@class='popupContent']/descendant::input[2]
this select the second input
Using /descendant::input
does what I need: grab all inputs and let me select by position.
How does //
differ? Why does it return only the first element and not the ones after?
I'm aware of this other question but the answer basically says they're aliases and point to the documentation, which I cannot understand and lacks a concrete example. Difference with that question is that my need is to select multiple children elements, and //
doesn't allow it.
child:: are your immediate children. descendant:: are your children, and their children, recursively.
The descendant axis indicates all of the children of the context node, and all of their children, and so forth. Attribute and namespace nodes are not included - the parent of an attribute node is an element node, but attribute nodes are not the children of their parents.
The difference between parent:: and ancestor:: axis is conveyed by their names: A parent is the immediately direct ancestor. So, yes /a/b/c/d/ancestor::*[1] would be the same as /a/b/c/d/parent::* .
The major difference between the following and following siblings is that the following sibling takes all the sibling nodes after the context but will also share the same parent.
The only difference between //X
and /descendant::X
is when X contains a positional predicate, for example //x[1]
vs /descendant::x[1]
. In this situation //x[1]
selects every x
element that is the first x
child of its parent element, whereas /descendant::x[1]
selects the first descendant x overall. You can work this out by remembering that //x[1]
is short for /descendant-or-self::node()/child::x[1]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With