13

Till now what all I understand is

  1. ::child looks for immediate child notes of the current node
  2. ::following looks for immediate child and sub child and so on of the current node.
  3. What is ::descendant then?

Can anyone help me understand with simple example?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
Pratiksha Jadhav
  • 175
  • 1
  • 3
  • 12
  • @JeffC As you have edited the question and removed the relevant `selenium-webdriver` tag you should have added either the `html` or `dom` tag. Without either of those tags simply `xpath` tag makes no sense. Moving forward please take care. – undetected Selenium Apr 22 '18 at 16:14
  • 2
    @DebanjanB: It's rather harsh (not to mention untrue) to say that an XPath question makes no sense without `html` or `dom` tags. XPath is bigger than Selenium, and JeffC's edit was entirely appropriate given that this question is about XPath itself, not any particular use of XPath in Selenium. – kjhughes Apr 22 '18 at 16:19
  • @kjhughes Completely agree with you that _XPath is bigger than Selenium_. But taking away OP's reference of `Selenium` tag related to _XPath_ is unethical too. – undetected Selenium Apr 22 '18 at 18:22
  • 1
    @DebanjanB: Unethical? Absolutely not. Removing the `selenium` tag is entirely correct, in fact. This question is intrinsic to XPath and has nothing whatsoever to do with Selenium. OPs often mistag. Correctly tagging mistakes as @JeffC has done is a valuable contribution. – kjhughes Apr 22 '18 at 18:49
  • You've already got a couple good answers. I would point you to the MDN reference on the subject. I've always found the MDN references really good at just about everything from JS to HTML and including XPath. https://developer.mozilla.org/en-US/docs/Web/XPath/Axes – JeffC Apr 23 '18 at 00:42

5 Answers5

17
  • child:: will select the immediate descendants of the context node, but does not go any deeper, like descendant:: does.
  • following:: will select all of the nodes that come after the context node and their descendant's, but that does not include the context node's descendants.
  • descendant:: will select all of the nodes along the child:: axis, as well as their children, and their children's children, etc..

Sometimes, a picture is worth a thousand words:

visualization of XPath axes

Image source, see Figure 3.5

It might be helpful to play with an XPath visualization tool, in order to evaluate your XPath expressions against some sample XML and see what is, and what is not, selected.

For example: http://chris.photobooks.com/xml

JeffC
  • 22,180
  • 5
  • 32
  • 55
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • Thank you so much! Image is bonus :-) – Pratiksha Jadhav Apr 22 '18 at 15:29
  • 1
    Hopefully not too pedantic but shouldn't "child:: will select the immediate children"... be " child:: will select the immediate *descendants*". There are no children other than immediate children. Where did you find the image? I like it and I'm gonna steal it as a reference. Thanks for the link also... I think I like that tool better than the one I've been using. – JeffC Apr 23 '18 at 00:19
  • Yes, immediate descendants would be more precise. I’ll update. The image should have been sourced. It was referenced in this article http://www.informit.com/articles/article.aspx?p=29844&seqNum=3: – Mads Hansen Apr 23 '18 at 00:38
8

XPath Axis Family Tree Analogy

The major XPath axes follow family tree terminology:

  • self:: is you.

Downward:

  • child:: are your immediate children.
  • descendant:: are your children, and their children, recursively.
  • descendant-or-self:: (aka //): are you and your descendants.

Upward:

  • parent:: is your mother or father.1
  • ancestor:: are your parent, and your parent's parent, recursively.
  • ancestor-or-self:: are you and your ancestors.

Sideways (consider elements earlier in the document to be younger):

  • previous-sibling:: are your younger siblings, in age order.
  • following-sibling:: are your older siblings, in age order.
  • previous:: are your younger siblings and their descendants, in age order.
  • following:: are your older siblings and their descendants, in age order.

1Not both, because XML elements have only a single parent.

kjhughes
  • 106,133
  • 27
  • 181
  • 240
3

XPath Axes

  • We will discuss the following terms with respect to the following HTML :

<?xml version="1.0" encoding="UTF-8"?>
<head>
 <meta content="image" property="my_property">
</head>
<body>
 <bookstore>

 <book>
   <title lang="en">Harry Potter</title>
   <price>29.99</price>
 </book>

 <book>
   <title lang="en">Learning XML</title>
   <price>39.95</price>
 </book>

 </bookstore>
</body>
  • child : Selects all children of the current node. For example, if your current node is <book>, the keyword child will select both the nodes :

    <title lang="en">Harry Potter</title>
    <price>29.99</price>        
    
  • following : Selects everything in the document after the closing tag of the current node. For example, if your current node is <head>, the keyword following will select all the nodes :

    <body>
        <bookstore>
    
        <book>
          <title lang="en">Harry Potter</title>
          <price>29.99</price>
        </book>
    
        <book>
          <title lang="en">Learning XML</title>
          <price>39.95</price>
        </book>
    
        </bookstore>
    </body>
    
  • descendant : Selects all descendants (children, grandchildren, etc.) of the current node. For example, if your current node is <body>, the keyword descendant will select all the nodes :

    <bookstore>
    
    <book>
      <title lang="en">Harry Potter</title>
      <price>29.99</price>
    </book>
    
    <book>
      <title lang="en">Learning XML</title>
      <price>39.95</price>
    </book>
    
    </bookstore>
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    Thanks for the explanation with example! It really helped – Pratiksha Jadhav Apr 22 '18 at 15:30
  • Your example HTML is not HTML, it's XML and it's not valid XML. `child` would select both sets of children (2 `title` and 2 `price`) since there are two `book` tags. `//following::head` pulls only the `head` tag, open to close tag, and nothing else. – JeffC Apr 23 '18 at 00:39
  • @JeffC Perhaps your understanding is not clear about `xpaths` and you can always raise a ticket to get help. Stackoverflow volunteers will be happy to help you out. – undetected Selenium Apr 23 '18 at 06:06
  • No, what I stated is the result of my testing. If you think otherwise, post the XPath you used to get the results you listed. – JeffC Apr 23 '18 at 13:15
2

Assume each nodes as box. now in an html page we have many boxes and each boxes other small boxes in it.

now when we say: child:: of a box - this would mean all the boxes inside the main box that we are looking at. this will only consider the boxes inside the current box. It won't look at the contents of the boxes.

following:: of a box - this would mean all the boxes after the box that I am looking at, this doesn't have anything to do with the current box that I am looking at.

descendant: it is like child, but the catch is - it looks all the boxes inside the node box and also look inside of each of the sub boxes too. child will only look for immediate boxes not inside each of the immediate boxes.

Jay
  • 336
  • 1
  • 4
  • 15
0

Child tag will only identify the child of the current node if the current node has a grandchild in it, it won't scan it, whereas the descendant tag will scan the grad child from the current node