Create XPath

In Selenium web automation, if the elements are not found by the general locators like name, id, tagname, class, etc. then we use XPath to find an element on the web page. In this tutorial, we will learn about how to create different XPath expression to find the complex or dynamic elements, whose attributes changes dynamically on refresh or any operations.

Topics to cover

What is XPath?

XPath is defined as XML path. It is a syntax or language for finding any element on the web page using XML path expression. XPath is used to find the location of any web/HTML element on a webpage using HTML DOM structure. The basic format of XPath is explained below with example.

Syntax for XPath:

// tagname [ @ attribute = 'value']

Types of X-path

There are two types of XPath:

1) Absolute XPath
2) Relative XPath
Absolute XPath:
It is the direct way to find the element, but the disadvantage of the absolute XPath is that if there are any changes made in the path of the element then that XPath gets failed. It starts with the single forward slash (/), which means you can select the web element from the root node. Below is the example of an absolute xpath expression:

<html>
    <body>
     <div><b>Selenium Absolute XPath</b></div>
     <div><p>paragraph text</p></div>
    </body>
</html>

Absolute xpath for above HTML to select <b></b> web element:
    /html/body/div[1]/b

Relative xpath:
Relative Xpath the path starts from the web element of the HTML DOM structure we select. It starts with the double forward slash (//), which means it can search the element anywhere at the webpage. You can start from the middle of the HTML DOM structure and no need to write long xpath. Below is the example of a relative XPath expression. Relative XPath uses common format used to find element.

<html>
    <body>
     <div><b class="relative-class">Selenium Absolute XPath</b></div>
     <div><p>paragraph text</p></div>
    </body>
</html>

Relative xpath for above HTML to select <b></b> web element by class attribute:
    //*[@class='relative-class']

XPath Axes

XPath Axes are methods to find dynamic elements, which is not possible to access/get by normal XPath method having no ID , Classname, Name, etc. Axes methods are used to find those elements, which dynamically change on refresh or any other operations. There are few axes methods commonly used in Selenium Webdriver like child, parent, ancestor, sibling, preceding, self, following, following-sibling etc.

Create XPath using different ways


By usign Attribute

We can create XPath expression to select HTML nodes or list of nodes on the basis of attributes like ID , Name, Classname, etc.

<html>
   <div>
    <div class="class-attribute">Div element with Class attribute</div>
    <div id="id-attribute">Div element with Id attribute</div>
    <input type="type-attribute">Input element with type attribute</input>
    <a href="href-attribute">Anchor element with href attribute</a>
  </div>
</html>

XPath for above HTML to select web element by different attributes:
    //div[@class='class-attribute']
    //div[@id='id-attribute']
    //input[@type='type-attribute']
    //a[@href='href-attribute']

By usign Contains()

Contains() is a method used in XPath expression. It is used when the value of any attribute changes dynamically. The contain feature has an ability to find the element with partial text in attribute value.

Syntax for XPath using Contains:

// tagname [ contains( @ attribute , 'contained value')]


In the example below, we tried to identify the element by just using partial text value of the attribute.

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="typeAttribute">Input element with type attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
</html>

XPath for above HTML to select web element by different attributes with contains method:
    //div[contains(@class,'classAttr')]
    //div[contains(@id,'idAttr')]
    //input[contains(@type,'typeAttr')]
    //a[contains(@href,'hrefAttr')]

It can select the multiple elements if the attribute contain value we take is similar to multiple elements. As showing below:

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="typeAttribute">Input element with type attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>
    <div class="classAttributeSecond">Another Div element with Class attribute</div>
    <div id="idAttribute">Another Div element with Id attribute</div>
  </div>
</html>

XPath for above elements:
    //div[contains(@class,'classAttr')]
Above XPath can access both div elements.


By usign And & OR

We can also create XPath by using AND & OR syntax. By using this we can get a single as well as multiple HTML elements.

Syntax for XPath by using AND

// tagname [ @ attribute = 'value'  and  @ attribute = 'value']


Syntax for XPath by using OR

// tagname [ @ attribute = 'value'  or  @ attribute = 'value']


<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>
    <div class="classAttributeSecond">Another Div element with Class attribute</div>
    <div id="idAttribute">Another Div element with Id attribute</div>
  </div>
</html>

XPath for above input element by using AND:
    //input[@type='submit' and @name="name"]

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>
    <div class="classAttributeSecond">Another Div element with Class attribute</div>
    <div id="idAttribute">Another Div element with Id attribute</div>
    <input type="text" name="textName">Input element with type and name attribute</input>
  </div>
</html>

XPath for above input elements by using OR:
    //input[@type='submit' or @name="textName"]
XPath with OR will select both input elements

By usign Starts-with()

Starts-with function use to find the elements whose value is dynamic. In this expression, match the starting text of the attribute is used to find the element whose attribute changes dynamically as well as whose value is static.

Syntax for XPath using Starts-with:

// tagname [ starts-with( @ attribute , 'contained value')]


In the example below, we tried to identify the element by just using start-with function.

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="typeAttribute">Input element with type attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
</html>

XPath for above HTML to select web element by start-with function:
    //div[starts-with(@id,'idAttr')]

By usign Text()

Text function use to find the elements by using text of element (inner HTML of elements). We can use this with contains() method also. And we can find dynamic as well as static elements by using text of innerHTML.

Syntax for XPath using Text():

// tagname [ text() = 'text value')]


In the example below, we tried to identify the element by just using Text() function.

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="typeAttribute">Input element with type attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
</html>

XPath for above HTML to select web element by Text() function:
    //div[text()="Div element with Id attribute"]

We can also use Text() with contains() method to get element. As example shows below

    //div[contains(text(),"Div element with Id")]

By usign XPath Axes method 'following'

Following axes method can access all the specific nodes(e.g ::div) after the current node selected.

NOTE:   We can also use the XPath Axes methods with contains and starts-with methods

Syntax for XPath using 'following' XPath axes method:

// tagname [ @ attribute = 'value'] //following::tagName


<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
  </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath for above input element by 'following' XPath axes:
    //input[@type='submit']//following::div
Above xpath by using 'following' XPath axes will select all the 'div' HTML elements after the current node we select.

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>[1]
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>[2]
  </div>
    <div id="idAttribute">Div element with Id attribute</div>[3]
</html>

By using the following way we can access the particular node that we want to access.

    //input[@type='submit']//following::div[2]

As in above we can select the 2nd div node after the current node

<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>
    <div id="idAttribute">Div element with Id attribute</div>
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>[1]
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>[2]
  </div>
    <div id="idAttribute">Div element with Id attribute</div>[3]
</html>

    //input[@type='submit']//following::div[3]

As in above we can select the 3rd div node after the current node

By usign XPath Axes method 'following-sibling'

Following-sibling axes method can access all the parallel/sibling/same level nodes of the current node.

Syntax for XPath using 'following-sibling' XPath? axes method:

// tagname [ @ attribute = 'value'] //following-sibling::tagName


<html>
   <div>
    <div class="classAttribute">Div element with Class attribute</div>[1]
    <div id="idAttribute">Div element with Id attribute</div>[2]
    <input type="submit" name="name">Input element with type and name attribute</input>
    <a href="hrefAttribute">Anchor element with href attribute</a>
  </div>
   <div>
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
  </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath for above input element by 'following-sibling' XPath axes:
    //input[@type='submit']//following-sibling::div

    //input[@type='submit']//following-sibling::div[2]

As in by using above XPath we can select the 2nd div node (and other type of nodes) after the current node.
Similarly we can access other nodes.

By usign XPath Axes method 'Ancestor'

'Ancestor' axes method can access all the parent/grand parent nodes of the current node.

Syntax for XPath using 'Ancestor' XPath axes method:

// tagname [ @ attribute = 'value'] //ancestor::tagName


<html>
   <div>[2]
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div>[1]
      <div id="idAttribute">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath for above input element by 'Ancestor' XPath axes:
    //input[@type='submit']//ancestor::div
Above xpath by using 'ancestor' XPath axes will select all the parent/grand parent 'div' HTML elements from current node we select.

    //input[@type='submit']//ancestor::div[1]

As in by using above XPath we can select the 1st div parent node from the current node.

By usign XPath Axes method 'Parent'

'Parent' axes method can access single level parent node of the current node.

Syntax for XPath using 'Parent' XPath axes method:

// tagname [ @ attribute = 'value'] //parent::tagName


<html>
   <div>
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">[1]
      <div id="idAttribute">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath for above input element by 'Parent' XPath axes:
    //input[@type='submit']//parent::div
Above xpath by using 'parent' XPath axes will select the parent 'div'( with parentIdAttribute css id property ) HTML element from current node.

By usign XPath Axes method 'Descendant'

'Descendant' axes method can access descendant (child/nested child) nodes of current node.

Syntax for XPath using 'Descendant' XPath axes method:

// tagname [ @ attribute = 'value'] //descendant::tagName


<html>
   <div class="descendant-class">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>[1]
    <div id="parentIdAttribute">[2]
      <div id="idAttribute">Div element with Id attribute</div>[3]
      <div id="idAttribute2">Div element with Id attribute2</div>[4]
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
    </div>
   </div>
</html>

XPath for above div element by 'Descendant' XPath axes:
    //div[@class='descendant-class']//descendant::div
Above xpath by using 'Descendant' XPath axes can select the all child/nested child div HTML element from current node.

We can also access the desired child nodes by the following ways
    //div[@class='descendant-class']//descendant::div[1]

    //div[@class='descendant-class']//descendant::div[2]

By usign XPath Axes method 'Child'

'Child' axes method can access child nodes of current node.

Syntax for XPath using 'Child' XPath axes method:

// tagname [ @ attribute = 'value'] /child::tagName


<html>
   <div>
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">
      <div id="idAttribute">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath for above div element by 'Child' XPath axes:
    //div[@id='parentIdAttribute']/child::input
Above xpath by using 'child' XPath axes will select the 'input' child node ( Can access any child node ) from current node.

Access Child/Nested Child nodes without XPath axes methods

By following way we can access child/nested child nodes of current node.

Syntax for XPath without using 'Child' XPath axes method:

// tagname [ @ attribute = 'value'] /tagName


<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">
      <div id="idAttribute">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath to access input node with top div element without using 'Child' XPath axes:
    //div[@id='parentIdAttribute']/input

Access Child Node
<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>[1]
    <div id="parentIdAttribute">[2]
      <div id="idAttribute2">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>[3]
</html>

XPath to access child anchor node without using 'Child' XPath axes:
    //div[@id='topParentId']/a

XPath to access child div node without using 'Child' XPath axes:
    //div[@id='topParentId']/div
or
    //div[@id='topParentId']/div[1]

XPath to access child div[2] node without using 'Child' XPath axes:
    //div[@id='topParentId']/div[2]

Access Nested Child Node
<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>[1]
    <div id="parentIdAttribute">[2]
      <div id="idAttribute2">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>[3]
</html>

XPath to access nested child input node without using 'Child' XPath axes:
    //div[@id='topParentId']/div[2]/input

Access parallel and parent nodes without XPath axes methods

By following way we can access parent or parallel nodes of current node.

Syntax for access parent node of current node without using XPath axes method:

// tagname [ @ attribute = 'value'] /..


Syntax for access parallel nodes of current node without using XPath axes method:

// tagname [ @ attribute = 'value'] /../tagName


<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">
      <div id="idAttribute2">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath to access parent div node with input element without using 'Child' XPath axes:
    //input[@type='submit']/..

<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">
      <div id="idAttribute2">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath to access parallel div node with id attribute2 by using input element as current node without using 'Child' XPath axes:
    //input[@type='submit']/../div
or
    //input[@type='submit']/../div[@id='idAttribute2']

<html>
  <div id="topParentId">
    <a href="hrefAttribute">Anchor element with href attribute</a>
    <div id="idAttribute">Div element with Id attribute</div>
    <div id="parentIdAttribute">
      <div id="idAttribute2">Div element with Id attribute</div>
      <input type="submit" name="name">Input element with type and name attribute</input>
      <a href="hrefAttribute">Anchor element with href attribute</a>
     </div>
   </div>
    <div id="idAttribute">Div element with Id attribute</div>
</html>

XPath to access top parent div node with id 'topParentId' by using input element as current node without using 'Child' XPath axes:
    //input[@type='submit']/../..