I was trying my hands on XPath for python-selenium.
I used this link for trying some XPaths' from tutorials:
So I tried these two variants of XPaths'.
This expression
//webengagedata//preceding-sibling::*
returned 14 results
And this expression
//webengagedata/preceding-sibling::*
returned 9 results
What does the "//" do to match 5 more results?
Single Slash “/” – Single slash is used to create Xpath with absolute path i.e. the xpath would be created to start selection from the document node/start node.
A double slash " // " means any descendant node of the current node in the HTML tree which matches the locator. A single slash " / " means a node which is a direct child of the current.
The absolute xpath has the complete path beginning from the root to the element which we want to identify. An absolute xpath starts with the / symbol. One drawback with the absolute xpath is that if there is any change in attributes beginning from the root to the element, our absolute xpath will become invalid.
'/' in XPath signifies looking for the element immediately inside its parent element. Whereas '//' signifies to look for any child or any descendant element inside the parent element.
/
vs //
in generalBoth child
(/
) and descendant-or-self
(//
) are axes in XPath.
/
is short for /child::node()/
.
Use /
to select a node's immediate children.
//
is short for /descendant-or-self::node()/
.
Use //
to select
a node, its children, its grandchildren, and so on
recursively.
/
vs //
with preceding-sibling::*
Your specific question asks about the difference between //preceding-sibling::*
and /preceding-sibling::*
.
Since your data is offsite and complex, let's consider instead this present and simpler XML:
<r>
<a/>
<b>
<c/>
<d/>
</b>
</r>
For this XML,
/r/preceding-sibling::*
selects nothing because r
has no
preceding siblings./r//preceding-sibling::*
selects the preceding siblings elements of
all of the descendant or self nodes of r
. That is, a
, b
, c
and d
.
(Remember, /r//preceding-sibling::*
is short for /descendant-or-self::node()/preceding-sibling::*
, not /descendant-or-self::*/preceding-sibling::*
) Note that even though b
and d
are predecessor siblings to no elements, they are predecessor siblings to text nodes because the above XML has whitespace after b
and d
. If all whitespace were removed, then only a
and c
would be selected./r/descendant::*/preceding-sibling::*
selects the preceding sibling elements of all descendant elements of r
. That is, a
and c
. Note that b
and d
are not selected because they are not preceding sibling elements to any descendant elements of r
-- unlike the previous example, text nodes do not qualify.For your example
//webengagedata/preceding-sibling::* ---> returned 9 results
Because there are only 9 tags which are exact sibling of webengagedata
tags thats why it is showing 9 records
//webengagedata//preceding-sibling::* ---> returned 14 results
Here it is considering child tags as well as biziclop said x/descendant-or-self::node()/y
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