How to write and Use XPath in Selenium (Using attributes, Axes, operators, functions)

One of the main reasons behind Selenium's popularity is that it supports multiple element locators. And one of them is XPath. XPath is one of the most powerful and flexible element locators in Selenium Webdriver. It helps you to navigate through the HTML structures of a page to locate an element using XPath.

In this guide, we will learn about what is XPath, how it works, and when to use it in Selenium test scripts. It is necessary to learn about different ways to find XPath of the element and how to write XPath syntax easily using real world examples. By the end, you will know the difference between absolute vs. relative XPath, common XPath expressions, and how to handle dynamic and nested elements like a pro.

How to find XPath in Selenium

What is XPath in Selenium?

Just like you use GPS to locate your car, XPath(XML Path Language) is used to locate an element on a webpage. It helps Selenium WebDriver testers to navigate through a webpage’s structure to find the exact element they need. No matter in which language you are working, the Same XPath will work in Java, Python, C#, and JavaScript languages.

When to use XPath In Selenium WebDriver?

Just recently, one of my colleagues was trying to locate an element by ID, but it was changing on page reloads. Then he tried to locate it by class name, but there was no unique class name of the element. Also, there was no option to locate element by name, tag name, etc. In such a scenario, the only way to locate the element is by XPath.

You can use XPath element locator:

  • When dealing with dynamic elements that change frequently.
  • When you need to navigate between elements (like finding a button inside a specific div).
  • When other locators don’t work or aren’t stable.
  • When working with complex web structures like SVG or Shadow DOM.

When not to use XPath in Selenium?

While XPath is a powerful locator, it’s not always the best choice. Here are some situations where you should avoid using XPath and opt for better alternatives.
  • When performance is important → XPath is the slowest option.
  • When an element has a unique and stable ID or Name. → Use By.id() to By.name().
  • When CSS Selectors can do the job → Use By.cssSelector()
  • When dealing with Shadow DOM → It is better to use JavaScript instead of XPath.
  • When working with SVG Elements → CSS Selectors is a better option.

Why Should You Use XPath?

If you are working with Selenium WebDriver automation, you have definitely heard about XPath. But do you know why to use XPath over other element locators like ID, Name, or CSS Selectors? Let us break it down in simple words.

XPath Can Find Any Element on the Page

Think of XPath as a GPS for your web page. It can find an element even if it is buried in the DOM (Document Object Model). When other locators fail, XPath will work perfectly in your test.

Great for Dynamic and Complex Elements

In modern websites, you might have seen that elements are generated on the fly. Meaning their IDs or classes change constantly. To locate such elements, you can build an XPath using flexible expressions instead of relying on static attributes.

You Can Move Around the DOM Like a Pro

Using XPath, one can navigate between elements. It is easy to find a parent, child, or sibling element. When elements do not have unique attributes, this is a super handy way to locate an element by referencing another nearby element.

Absolute vs. Relative XPath

Absolute XPath (/html/body/div/input) is like providing a full direction from the beginning of the page. It is precise, but fragile (one small change can break your XPath).

Relative XPath (//input[@type='text']) is a more flexible way to locate an element based on its attributes, no matter where they are on the page.

Powerful Search Functions

XPath has built-in search functions like contains(), starts-with(), and text(). It makes it easier to find an element on the web page.

Example

  • contains(): //button[contains(text(),'Login')]: Finds buttons with "Login" in the text.
  • starts-with(): //input[starts-with(@id,'user')]: Finds input textbox elements where the ID starts with "user" text.
  • text(): //h1[text()='Hello']: Finds an element with exact text "Hello".

Handles Shadow DOM & SVG Elements

It is hard or impossible to locate elements like SVG graphics or Shadow DOM elements using other element locators. But you can access such elements easily using XPath.

Combine Multiple Conditions for Precision

Are you looking to find a specific input field? You can combine conditions like this to find an element using multiple conditions. Example: //input[@type='text' and @name='username'].

What are the different types of XPath?

Mainly there are two types of XPath that you can use in Selenium. Absolute XPath and Relative XPath. Each type has its own use case, advantages, and limitations. As experts suggest, Relative XPath is more reliable than the Absolute XPath. 

Let’s go through them step by step to learn how to build XPath with examples.

Absolute XPath (Avoid If Possible!)

Absolute XPath Provides exact path from the root <html> tag to your element. But it can break if page structure changes.

It is just like giving a direction to someone like "Go to the first building, enter the second room, then open the first drawer."

Example of Absolute XPath:

/html/body/div[1]/form/input
It will locate the input element which is present on the given full path.

Pros and Cons of Absolute XPath

Pros of Absolute XPath:
  • Precise: Points directly to your targeted element.
  • Easy to generate: You can easily copy it from your browser's dev tool.
Cons of Absolute XPath:
  • Easily breaks: It can break even if there is a small change in page structure.
  • Hard to maintain: You need to update the XPath even a small update on the page.
  • When to use?: Only as a last resort when nothing else works.

Relative XPath (The Smart Choice!)

Relative XPath can find an element from anywhere in the DOM. It does not follow the strict path, but looks for the element based on its properties.

Example of Relative XPath

//input[@id='username']
It will locate the <input> field with the ID username from anywhere on the page.

Pros of Relative XPath

  • More flexible: It works even if the structure of the page changes.
  • Easier to maintain: Doesn’t break with minor updates.
  • More readable: You can locate elements by attributes, text, or relationships.
  • When to use?: Always prefer relative XPath over Absolute XPath. It is the recommended method for XPath.

All Possible Ways to Write XPath in Selenium

Now let us see how you can write XPath of an element using different Attributes and functions. 

We will use the below given sample login form for demonstration.

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <div class="container">
        <form id="loginForm">
            <label for="username">Username:</label>
            <input type="text" class="input-field" id="uname" name="username" placeholder="Enter username">

            <label for="password">Password:</label>
            <input type="password" id="pass" name="password" placeholder="Enter password">

            <button type="submit">Login</button>
        </form>
    </div>
</body>
</html>

1. XPath Using Different Attributes

You can locate elements using different attributes like id, name, class, and type.

Here are examples of building XPath using id, name, class, and type attributes.

Using ID attribute

If an element has an ID attribute, then you can use it to build XPath as below.

//input[@id='uname']
This XPath will locate an element with attribute id=uname.

Using Name attribute

If an element does not have an ID but a name attribute is available, then you can utilize it to generate XPath. Here is an Example:

//input[@name='username']
This XPath will locate an element with attribute name=username.

Using Class attribute

Same as ID and Name attributes, you can use the class attribute as well.

//input[@class='input-field']
This XPath will locate an element with attribute class=input-field.

Using Type attribute

You can use 

//input[@type='password']
This XPath will locate an element with attribute type=password.

2. XPath Using contains() Function

You can use the contains function in XPath as below when the element has a dynamic attribute value.

//input[contains(@name, 'user')]

It will find any input field where the name contains text "user" (e.g., user123, user_login).

//button[contains(text(), 'Login')]

It will find a button that contains the text "Login" in its text.

3. XPath Using starts-with() Function

You can use the starts-with() function when an element’s attribute starts with a fixed text pattern.

//input[starts-with(@name, 'user')]
It will locate elements with name="username", name="user123", etc.

4. XPath using text() Function

You can use the text() function to find elements by their exact text value.

//button[text()='Login']
It will find a button with exact text "Login".

5. XPath Using Logical Operators (and, or)

You can use multiple conditions to narrow down your selection.

//input[@type='text' and @name='username']

It will find an <input> field that is both text-type and has the name "username".

//button[@type='submit' or text()='Login']

It will locate a button with either type="submit" or text "Login".

6. Parent-Child & Descendant XPath

Direct Child (/)

To find elements that are direct children of a parent, you can write XPath as below.

//form/input
This XPath will find input fields that are direct children of the <form>.

Any Descendant (//)

One can use given XPath to find any input field inside a <div>, even if it is deeply nested.

//form/input

7. Navigating the DOM (Parent, Sibling, Ancestors)

Moving to Parent (..)

//input[@name='password']/..

It will find the parent element of the password input field.

Finding Siblings

Next Sibling (following-sibling)

//label[@for='username']/following-sibling::input

It will locate the input field immediately after the "Username" label.

Previous Sibling (preceding-sibling)
//input[@id='pass']/preceding-sibling::label
It will locate the label before the password input field.

8. XPath Using Position (first(), last(), [n])

Locate the first element

//input[1]
It will locate the first input field on the page.

Locate the last element

//table/tbody/tr[last()]

Finds the last row in a table.

Specific Position (nth element)

//input[2]
This XPath will find the second input field from the page.

You can refer to this xpath cheat sheet which covers almost all functions, axes, predicts, expressions, and selectors.

Where to practice XPath?

You can use the Selectoshub online practice page to try all possible variations of XPath.

Using XPath Axes in Selenium WebDriver With Examples

You can use XPath Axes to navigate up, down, and sideways in the DOM. Using Axes, you can traverse the hierarchy to locate elements dynamically.

When to Use XPath Axes?

  • When elements do not have any unique attributes like id or name.
  • When you need to locate an element relative to another.
  • When you are dealing with complex, nested structures.

List of XPath Axes with example

  • child:: -> Selects Direct Children
    • Example: //form/child::input (It will select all input fields inside the <form>.)
  • parent:: -> Selects Parent of an Element
    • Example: //input[@id='password']/parent::form (Finds the form that contains the password field.)
  • descendant:: -> Selects All Nested Elements
    • Example: //div/descendant::input (Finds all input fields inside the <div>.)
  • ancestor:: -> Selects All Ancestor Elements (Upwards Traversal)
    • Example: //input[@id='username']/ancestor::div (Finds the div container of the username input field.)
  • following:: -> Selects All Elements After the Current Element.
    • Example: //label[@for='username']/following::input (Finds the first input field after the username label (i.e., the username input))
  • following-sibling:: -> Selects Next Sibling Elements
    • Example: //label[@for='username']/following-sibling::input (Finds the username input field, which is the next sibling of the label.)
  • preceding:: -> Selects All Elements Before the Current Element.
    • Example: //input[@id='password']/preceding::label (Finds the label for username, which comes before the password input.)
  • preceding-sibling:: -> Selects Previous Sibling Elements.
    • Example: //input[@id='password']/preceding-sibling::label (Finds the password label, which is the sibling before the password input field.)
  • self:: -> Selects the Current Element Itself.
    • Example: //input[@id='username']/self::input (Finds itself (username input field))
For best practices, you can use following-sibling:: and preceding-sibling:: to select nearby elements efficiently. Always prefer descendant:: for deep nested paths to avoid brittle XPath. Try to use ancestor:: to move up and find parent elements dynamically. following:: and preceding:: are slower, so avoid using them if not necessary.

Handling Customized Dynamic XPath In Selenium WebDriver

You need to customize XPath when the element's attributes change frequently. If an element's id, name, or class values are not static, Regular XPath expressions will not work for you. In such cases, you need to use advanced dynamic XPath.

Here are a few smart and advanced XPath examples to build and handle dynamic XPath for an Element
  • Using contains() for Partial Matching: //input[contains(@id, 'user_')]
  • Using starts-with() for Matching Beginning Text: //input[starts-with(@id, 'user_')]
  • Using text() for Text-Based Matching: //button[text()='Login']
  • Using or and and for Multiple Conditions: //input[@type='text' or @placeholder='Enter username']
  • Using following-sibling:: to Locate Elements Dynamically: //label[text()='Username:']/following-sibling::input
  • Using ancestor:: to Find Parent Elements: //input[@id='pass_987']/ancestor::form
  • Using last() to Get the Last Element in a List: //input[last()]

How to Use XPath in Java, Python, and C# With Selenium

For your knowledge, XPath is not dependent on any language. You can use the same XPath in all three languages.

Using XPath in Selenium With Java Example

    WebElement username = driver.findElement(By.xpath("//input[@id='username']"));
    WebElement password = driver.findElement(By.xpath("//input[@type='password']"));
    WebElement loginButton = driver.findElement(By.xpath("//button[contains(text(), 'Login')]"));

Using XPath in Selenium With Python Example

    IWebElement username = driver.FindElement(By.XPath("//input[@id='username']"));
    IWebElement password = driver.FindElement(By.XPath("//input[@type='password']"));
    IWebElement loginButton = driver.FindElement(By.XPath("//button[contains(text(), 'Login')]"));

Using XPath in Selenium With C# Example

    username = driver.find_element(By.XPATH, "//input[@id='username']")
    password = driver.find_element(By.XPATH, "//input[@type='password']")
    login_button = driver.find_element(By.XPATH, "//button[contains(text(), 'Login')]")

Best XPath extensions and Plugins For Chrome Browser

Finding XPath for each and every element is time-consuming, right? Here is a list of the top 4 free Chrome extensions for 2025 that you can use to find XPath of any web element.

Frequently Asked Selenium Interview Questions on XPath

XPath is a very important and crucial topic in an interview. Generally, interviewers are asking the following tricky questions.

1. What is XPath in Selenium, and why do we use it?

In Selenium, XPath is a way to locate an element on the page when other locators like ID, name, or find element by class name are not working. It allows you to navigate through the HTML structure and pinpoint elements precisely.

So, why use XPath?
  • Some elements have dynamic changing attributes. XPath works well in this scenario.
  • It has built-in functions and methods to search elements by text, partial text, parent-child relationships, or even positions.
  • It is super flexible compared to other locators.

2. What is the difference between Absolute XPath and Relative XPath?

Absolute XPath is just like giving someone turn-by-turn directions from the homepage to a specific section. It is a full path from the main HTML tag to the element. This XPath will break if anything changes in the page structure.

Example: /html/body/div[1]/table/tbody/tr[2]/td[1]

Relative XPath is more flexible as it can search from anywhere in the document instead of the root. Less chances to break when the UI updates.

Example: //table[@id='userTable']//tr[2]/td[1]

3. How do you handle dynamic elements with XPath?

Sometimes, Element's attributes like ID and name keep changing when the page reloads. In such scenarios, we can use the following smart techniques of XPath to handle them easily.
  • contains(): We can use contains() function when a part of attributes remain same
    • Example: //input[contains(@id, 'email')]
  • starts-with(): If the attribute's initial part remains the same, we can use the starts-with() function.
    • Example: //button[starts-with(@class, 'submit-btn')]
  • ends-with(): One can match the end part of an attribute if it remains the same.
    • Example: //input[ends-with(@class, 'txt')]
  • text(): It is useful when you are looking to locate an element based on visible text.
    • Example: //a[text()='Login']
  • last(): You can match the last matching element in a group using this function.
    • Example: (//input[@type='text'])[last()]

4. How do you find a parent or sibling element using XPath?

We can use XPath axes to navigate up, down, and sideways in HTML structure as follows.
  • To find the parent element, we can use parent::
    • Example: //input[@id='username']/parent::div
  • To find the next sibling element, we can use the following-sibling::
    • Example: //label[text()='Username']/following-sibling::input
  • To find the previous sibling element, we can use preceding-sibling::
    • Example: //input[@id='password']/preceding-sibling::label
These are very useful axes when a unique identifier of the element is not available. You can locate an element using the nearby element's reference.

5. What are XPath operators, and how do they help?

XPath also comes with handy operators that make searching even more powerful. Here is a list of operators with examples.
  • and Operator: You can use it to match both conditions.
    • Example of and Operator: //input[@type='text' and @name='email']
  • or Operator: Useful when looking to match either condition.
    • Example or Operator: //button[@id='submit' or @class='btn']
  • = Operator: Check for exact match.
    • Example of = Operator: //a[@href='login.html']
  • != Operator: Not equal to
    • Example of != Operator: //input[@type!='password']

You can learn and read frequently asked Selenium Interview Questions and Answers if you are preparing for an interview.

XPath is like a Swiss Army knife for Selenium. It is so powerful, flexible and works very well when other locators struggle or fail. However, it is slower than CSS Selectors. So use it wisely. If an element has a stable ID, name, tagname or Class, go for that first. But when things get tricky, XPath is your best friend!














No comments:

Post a Comment