The XPath Cheat Sheet Every Developer Needs

xpath cheat sheet

When you develop a web application, your app inevitably interacts with elements on a website. XPath helps your app target various parts of XML and HTML documents. Still, constructing valid XPath expressions in app development can be tiring and repetitive. 

Moreover, you may be interested in developing secure web apps and defending yourself against automated attacks such as those via XPath injection. You could make your websites automation-proof, such as forcibly reloading the captcha only for bot-driven actions and identifying mechanical activity. Thus, learning XPath is essential for cyber security.

Here is where our XPath cheat sheet plays a pivotal role. This cheat sheet is concise and saves you time checking if your XPath syntax is correct. It’s also precise and will help you troubleshoot problem areas. It’ll speed up your overall learning process in web development, cyber security, and everything related.

Keep this XPath cheat sheet handy by downloading it here . When you’re ready, let’s dive in.

XPath Cheat Sheet Search

Search our XPath cheat sheet to find the right cheat for the term you're looking for. Simply enter the term in the search bar and you'll receive the matching cheats available.

What Is XPath?

A popular functionality in web development is automation: the hands-free manipulation of a website's Document Object Model (DOM). If your target websites don’t support application programming interface (API) calls directly or via Hootsuite, Buffer, or Zapier, how do you write programs to locate web elements in your browser and act upon them?

A popular functionality in web development is automation: the hands-free manipulation of a website's Document Object Model (DOM). If your target websites don’t support application programming interface (API) calls directly or via Hootsuite, Buffer, or Zapier, how do you write programs to locate web elements in your browser and act upon them?

Here is where XPath plays a role. XPath, short for “XML Path Language,” is a compact way of teaching a web automation engine such as Selenium WebDriver to locate elements in an HTML source code document.

XPath is compact because it represents nodes in an XML or HTML document as a directory path with forward slashes (/) as the main delimiter. Parking an XPath as a string rather than a standard selector path takes up less memory. Here’s the same HTML element represented both ways:

To demonstrate its compactness, the XPath string is only 55% the length of that of the selector path.


As amazing as XPath appears to be, learning XPath requires a working knowledge of HTML, CSS, and JavaScript/jQuery, and the ability to open the Inspector panel in your preferred browser:

If you’re confident in the above, following the examples in this XPath cheat sheet is easier. If not, bookmark this page and come back when you’re ready.


XPath expressions include XPath queries, which typically refer to absolute and relative XPaths, and XPath function calls, which can be independent of an XML or HTML document. Make sure to distinguish XPath queries from XQuery, a query-based functional programming language outside this cheat sheet’s scope yet supports XPath.

This XPath cheat sheet differs from what we’re used to writing because we’ve found the best way to learn XPath is by looking at multiple examples and intuitively deriving the XPath pattern from them. When in doubt, use this website to test out XPath queries.

The table below presents static XPath examples, all extracted via the Inspector (see Prerequisites) from functional websites at the time of writing. The general XPath syntax follows later below.

HTML elementSelector pathRelative XPathAbsolute
<html> tag of an HTML documenthtml/html/html
<body> tag on a websitebody/html/body/html/body
Title of a websitehead > title/html/head/title/html/head/title
The modifiable titular text box on a to-do list website#title//*[@id="title"]/html/body/div[1]/input
A blue “Verify you are human” button#challenge-stage > div > input//*[@id="challenge-stage"]/div/input/html/body/div[1]/div /div[1]/div/input
“Share Feedback” button (DuckDuckGo)#web_content_wrapper > div.serp__bottom-right.js-serp-bottom-right > div > div > a//*[@id="web_ content_wrapper"] /div[2]/div/div/a/html/body/div[2] /div[5]/div[2]/div/div/a
Dropdown button on a website menu#navbarDropdown4//*[@id="navbarDropdown4"]/html/body/div[1]/div/nav /div/div[2]/div[1]/ul/li[4]/a
Hyperlink portion of a Google search result#rso > div:nth-child(1) > div > div > div.Z26q7c.
UK95Uc.jGGQ5e > div > a > h3
//*[@id="rso"]/div[1] /div/div/div[1]/div/a/h3/html/body/div[7]/div/


We have a few observations from the table above:

  • The absolute XPath examples above begin with /html, the root (most basic, primitive parent) node of every HTML document.
  • All relative XPath expressions above begin with //*.
    • Why not // as most other XPath resources say?
    • The reason for * is that it’s a wildcard or placeholder for the node (HTML tag, in this case) in question, as you will see shortly. You may replace * with a suitable HTML tag, and the XPath will still work.
  • The format for getting a node with a particular ID is //*[@id="name-of-id"].
  • The selector constraint [ ] distinguishes between different nodes sharing the same HTML tag by their indices, such as <div>. For example, div[2] refers to the second <div> sharing the same parent node.

Hence the basic XPath syntax is as follows, reusing the to-do list example above:

XPath typeBasic XPath syntaxExample
Relative, node attribute carrying a value//nodeX[@attribute="value"]//input[@id="title"]

What Is An XPath Axis?

The symbol @ in XPath expressions has to do with XPath axes. An XPath axis describes a relationship to the current node on the XML/HTML hierarchy tree. The two-colon syntax (::) specifies conditions on the axis.

A step is an XPath segment between consecutive forward slashes (/), such as html in absolute paths. An axis can be a step.

In the table below, we leave a cell empty if no corresponding abbreviation or equivalence relationship exists. Note the symbols for self/parent axes are similar to those of the current/parent directory in scripting languages.

AxisAbbreviation… is short for …Description
ancestorSelect all ancestors (parent, grandparent, etc.) of the current node
ancestor-or-selfSelect all ancestors (parent, grandparent, etc.) of the current node and the current node itself
attribute@@href == attribute::hrefSelect all attributes of the current node
childdiv == child::divSelect all children of the current node
descendantSelect all descendants (children, grandchildren, etc.) of the current node
descendant-or-self//// == /descendant-or-self::node()/Select all descendants (children, grandchildren, etc.) of the current node and the current node itself
followingSelect everything in the document after the closing tag of the current node
following-siblingSelect siblings (nodes with the same parent node) below the current node
namespaceSelect all namespace nodes of the current node
parent.... == parent::node()Select the parent of the current node
precedingSelect all nodes that appear before the current node in the document, except ancestors, attribute nodes, and namespace nodes
preceding-siblingSelect siblings (nodes with the same parent node) above the current node
self.. == self::node()Select the current node

This short table explains XPath wildcard symbols:

XPath wildcardDescriptionExample
*Match element node//a/*
@*Match attribute node; same as attribute::*//input[@*]
node()Match node of any kind//head/node()
text()Match text node, namely the content between <tag> and </tag>//title/text()
comment()Match comment node <!-- … -->//footer//comment()
processing-instruction()Match any node of the format <?name value?>, e.g., <?xml catalog>//*/processing-instruction()


XPath selectors are where XPath expressions and CSS selectors intersect. The table below illustrates the relationship between XPath axes and their corresponding CSS selectors:

XPathCSS selector
//div/following-sibling::pdiv ~ p
//h1/preceding-sibling::[@id="wrong"]#wrong ~ h1
//li/ancestor::olol > li
//li/ancestor::ol[1]ol + li
//ul[li]ul > li

Order selectors enclose ordinal numbers or last() with the selector constraint [ ]:

XPath with order selectorsCSS selector
//ul/li[1]ul > li:first-of-type
//ul/li[2]ul > li:nth-of-type(2)
//ul/li[last()]ul > li:last-of-type
//*[1][name()="a"]ul > li

Attribute selectors focus on HTML tag attributes:

XPath with attribute selectorsCSS selector
//section[.//h1[@id='intro']]section > h1#intro
//a[starts-with(@href, '/')]a[href^='/']
//a[ends-with(@href, '.pdf')]a[href$='pdf']
//a[contains(@href, '://')]a[href*='://']
//ol/li[position()>1]ol > li:not(:first-of-type)

Pro tip: You can chain XPath selectors with consecutive selector constraints, but the order matters. For example, these two XPath queries have different meanings, as explained below:

  • //a[1][@href='/']
    • Get the first <a> tag and check its href has the value '/'.
  • //a[@href='/'][1]
    • Get the first <a> with the given href.


You can use logical operators in XPath queries:

|Union: join two XPath expressions//a | //span
+Addition2 + 3
-Subtraction3 - 2
*Multiplication2 * 5
divDivision5 div 2
!=Not equalnumber(//p/text())!=9.80
<Less thannumber(//p/text())<9.80
>=Less than or equal tonumber(//p/text())<=9.80
>Greater thannumber(//p/text())>9.80
>=Greater than or equal tonumber(//p/text())>=9.80
oror//div[(x and y) or not(z)]
andand//div[@id="head" and position()=2]
modModulus (division remainder)5 mod 2


The table below illustrates functions used in XPath expressions. Some, such as boolean(), are standalone XPath expressions. Some of the following appear in the examples above.

name()Return the name of the node (e.g., HTML tag)//*/a/../name()
text()Return the inner text of the node, excluding the text in child nodes//div[text()="Submit?"]/*/text()
lang(str)Determine whether the context node matches the given language (Boolean)//p[lang('en-US')]
namespace-uri()Return a string representing the namespace URI of the first node in a given NodeSet. This function applies to XML documents.//*[@*[namespace-uri()='']]
count()Count the number of nodes in a NodeSet and return an integer//table[count(tr)=1]
position()Return a number equal to the context position from the expression evaluation context//ol/li[position()=2]
string()Convert an argument to a stringstring(//div)
number()Convert an object to a number and return the numbernumber(//img/@width)
boolean()Evaluate an expression and return true or false. Use this to check for the existence of nodes/attributes.boolean(//div/
not(expression) Evaluates Boolean NOT on an expressionbutton[not(starts-with(text(),"Submit"))]
contains(first, second)Determine whether the first string contains the second string (Boolean)//button[contains(text(),"Go")]
starts-with(first, second)Check whether the first string begins with the second string (Boolean)//[starts-with(name(), 'h')]
ends-with(first, second)(Only supported in XPath 2.0; Selenium supports up to XPath 1.0)
Check whether the first string ends with the second string (Boolean)
//img[ends-with(@src, '.png')]
concat(x,y)Concatenate two or more strings x,y and return the resulting string.
The example checks if the attribute foobar is part of a space-separated list.
//div[contains(concat(' ',normalize-space(@class),' '),' foobar ')]
(given_string, start, length)
Return a part of a given_string beginning from the start value with a specified lengthsubstring("button", 1, 3)
Return a string that is part of a given_string before a given substringsubstring-before("01/02", "/")
Return a string that is part of a given_string after a given substringsubstring-after("01/02", "/")
translate()Evaluate a string and a set of characters to translate and return the translated stringtranslate('The quick brown fox.', 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
normalize-space()Remove redundant white space characters and return the resulting stringnormalize-space('  hello  world   !   ')
string-length()Return a number equal to the number of characters in a given stringstring-length('hello world')

Pro tip: You can use nodes inside functions. Examples:

  • //ul[count(li) > 2]
    • Check if the number of <li> tags inside the <ul> tag is greater than two.
  • //ul[count(li[@class='hide']) > 0]
    • Check the number of <li> tags with class “hide” inside the <ul> tag is a positive integer.

More Usage Examples

Here’s how to extract data from a specific element:

//span/text()Get the inner text of the <span> tag. In the example below, "Click here" is the result.
<span>Click here</span>
//*/a[@id="attention"]/../name()Find the name of the parent element to an <a> tag with id="attention"
//body//comment()Get the first comment under the <body> tag.

Extracting data from multiple elements is straightforward. The following XPath expressions apply to the same HTML example:


  <a class="pink red" href="">oranges</a>

  <a class="blue" href="">and lemons</a>

  <a class="green" href="">apple</a>

  <a class="violet" href="">honey</a>

  <a class="amber" href="">mint</a>

  <input type="submit" id="confirm">Go!</input>


//a/@hrefGet the URLs (the href string value) in all <a> tags:
//a/text()Get the inner text of all <a> tags:
and lemons
//a/@classGet the classes of all <a> tags:
pink red

The table below shows ways to extract data from an element based on its attribute value—note the mandatory use of @ in the final step of each XPath query:

XPath queryDescription
//a[@href=""]/@classGet the class in the <a> tag where the href string value is "":
//*[contains(@class, "red")]/@hrefGet the URL (the href string value) in any tag with the class "red":
//input[@id="confirm"]/@typeGet the type attribute of an <input> tag with id="confirm":

If you want to extract data from an element based on its position, check out these examples:

XPath queryDescription
//table/tbody/tr[3]Get the third <tr> element in a table
//a[last()]Get the last <a> tag in the document
//main/article/section[position()>2]/h3Get the <h3> tags in all <section> tags after the second instance of <section>

Now that you’ve made it to the last section of this cheat sheet, here are three real-life XPath examples of XPath in Selenium. (These are taken from my web development projects.)

1. Absolute XPath expressions to get the “Accept All Cookies” footer bar out of the way:

  • cookiespress="/html/body/div[1]/main/div/div/div/div/div[4]/div/div/div[2]/div/button[1]"
  • loginwith="/html/body/div[1]/main/div/div/div/div/div[1]/div[1]/div[2]/form/div[1]/span"
Examples of absolute XPath expressions in a real web app

2. This relative XPath expression maps to a pop-up triggered when a user successfully posts to a certain social media platform: "//*[@class='Toastify__toast--success']"

Real-life XPath example: "//*[@class='Toastify__toast--success']"

3. The following Python function handles XPath error messages "//span[data-text='⚠️ error posting status, request failed with status code 403/429']":

Real-life XPath example: "//span[data-text='⚠️ error posting status, request failed with status code 403/429']"


We hope this comprehensive XPath cheat sheet helps you accelerate your IT learning journey, especially in application development and security. You can read about XPath injection attacks and testing for it. For more information, check out our blog articles on coding and our resources on development, security, and operations (DevSecOps) below:


Level Up in Cyber Security: Join Our Membership Today!

vip cta image
vip cta details
  • Cassandra Lee

    Cassandra is a writer, artist, musician, and technologist who makes connections across disciplines: cyber security, writing/journalism, art/design, music, mathematics, technology, education, psychology, and more. She's been a vocal advocate for girls and women in STEM since the 2010s, having written for Huffington Post, International Mathematical Olympiad 2016, and Ada Lovelace Day, and she's honored to join StationX. You can find Cassandra on LinkedIn and Linktree.