October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Select the Last Element in XPath

Use XPath last() correctly: select the final child, last descendant, or last node in a grouped document-wide result without scope surprises.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use item[last()] to select the last matching item child in the current XPath context. To select the last item in a complete document-wide result, group the path first: (//item)[last()]. Those expressions are not interchangeable: //item[last()] can return one last item child for every matching parent.

The expression you need

XPath evaluates a predicate against a context list. The last() function returns the size of that list, and positions are one-based. Therefore, item[last()] keeps the item whose position equals the list size—the final matching child of the current context node.

item[last()]

The same relationship can be written explicitly as item[position() = last()]. The shorter form is normally clearer.

Scope determines what “last” means

Before writing the predicate, describe the set you want in ordinary language. Are you asking for the last child under each parent, the last descendant under one node, or the last node in the entire document result? Attach [last()] to the step or grouped path that represents that set.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Last child of the current context node

para[last()]

This selects the last para child of the node supplied as the context. It does not search arbitrary descendants.

Last matching child under each parent

//item[last()]

The abbreviated // path expands through descendant-or-self steps. The predicate is applied to the item child step reached for each parent, so the result can contain several nodes: one last item child for every parent that has matching children.

For example, if three sections each contain several item elements, this expression may return three nodes rather than one. That is correct XPath behavior, not a failure to find the document’s final item.

Last item in the whole document result

(//item)[last()]

Parentheses force XPath to evaluate all matching item nodes first. The outer predicate then keeps the final node in that complete result.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Last descendant beneath the current node

(.//item)[last()]

The leading dot makes the scope explicit: begin at the supplied context node, search its descendants, then select the last item in that scoped result. This is usually safer than relying on an implicit document context in reusable automation code.

Rank #2
XPath 2.0 Programmer's Reference
  • Used Book in Good Condition

Common expressions compared

Goal XPath Possible result
Last matching child of the current node item[last()] One node, if the context has matching children
Last item child for every matching parent //item[last()] Zero, one, or many nodes
Last item in the complete document result (//item)[last()] At most one node
Last item descendant of the current context (.//item)[last()] At most one node in that scope
Last warning paragraph child para[@type='warning'][last()] The final warning paragraph child

Filter first, then select the last

Adjacent predicates are evaluated from left to right. This lets you define the candidate set before choosing its final position.

para[@type='warning'][last()]

Here XPath first keeps warning paragraphs, then selects the last warning paragraph. Reversing the predicates changes the meaning:

para[last()][@type='warning']

This tests only whether the last para child is a warning. If the final paragraph has another type, the result is empty—even when an earlier warning paragraph exists.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Other useful filter combinations

  • item[@status='active'][last()] selects the last active item in the relevant child sequence.
  • (.//button[@aria-label='Next'])[last()] selects the final matching descendant button in the current scope.
  • (//article[contains(@class, 'post')])[last()] selects the final article from the document-wide filtered result.

XPath positions are one-based

The first node has position 1, not 0. Thus item[1] selects the first item in the predicate context, while item[last()] selects the final one. To select the second-to-last item, use item[last() - 1], provided at least two matching items exist.

Numeric predicates are shorthand for position tests. item[3] means the item whose context position is three; it is equivalent to item[position() = 3].

How to use last() in browser JavaScript

Document.evaluate() evaluates XPath against a document or another node. Its second argument is the context node, so relative expressions depend on the node you provide.

const result = document.evaluate(
  "(.//item)[last()]",
  document,
  null,
  XPathResult.FIRST_ORDERED_NODE_TYPE,
  null
);
const lastItem = result.singleNodeValue;

For a body-scoped search, pass document.body and use a relative expression:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const result = document.evaluate(
  "(.//h2)[last()]",
  document.body,
  null,
  XPathResult.FIRST_ORDERED_NODE_TYPE,
  null
);
const lastHeading = result.singleNodeValue;

If you expect several results, request an iterator or snapshot instead of FIRST_ORDERED_NODE_TYPE. A correct XPath can still appear to “return the wrong thing” when the host API deliberately reads only one node.

A practical method for building the XPath

  1. Name the scope. Decide whether the set is the current node’s children, descendants of a supplied node, or the whole document.
  2. Write the base selection. Start with a node test such as item, para, or *, then add attributes or other conditions.
  3. Choose the grouping. Keep [last()] on a repeated child step for “last per parent”; wrap the complete path in parentheses for “last overall.”
  4. Order predicates. Put type, class, status, or text filters before [last()] when the last node must satisfy those conditions.
  5. Verify the host context. Check which node the automation framework passes as the context and whether it supports the XPath functions you use.
  6. Inspect the cardinality. If several nodes are returned, you probably selected a last-per-parent step. If none are returned, check names, namespaces, scope, and predicate order.

Troubleshooting unexpected results

“Why does //item[last()] return several items?”

Because the predicate is evaluated for the item step under each relevant parent. Use (//item)[last()] for one final item across the complete document result, or (.//item)[last()] for one final item within the current node’s descendants.

The result is empty

  • Confirm that the element name and spelling match the source tree.
  • Check whether the context node is the document, a component root, or a different subtree.
  • Look for XML namespaces. A prefixed XPath name must be bound to the correct namespace URI by the host API; an unprefixed name does not automatically match namespaced XML elements.
  • Determine whether an earlier predicate removed every candidate before [last()] ran.

The last element is not the one visible on screen

XPath evaluates the parsed DOM, not visual order. Client-side rendering, hidden nodes, template content, and later DOM mutations can change what exists when the expression runs. Evaluate after the page or component has finished inserting the target nodes, and scope the expression to the intended container.

A framework reports multiple matches when one was expected

Use grouped scope and an API that requests a single node, or assert the expected count before selecting. Do not silently take the first result unless “first in document order” is actually your requirement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compatibility is unclear

The basic last(), position(), predicates, and grouping shown here are established XPath syntax, but host products differ in XPath version, namespace APIs, and result handling. Check the implementation used by your browser, XML processor, or automation framework before relying on version-specific functions beyond this core syntax.

Testing expressions quickly

In browser developer tools, test a candidate against a known page and compare both scope and count. Start broad, then narrow:

  1. Evaluate //item to see every document-wide match.
  2. Evaluate //item[last()] and inspect whether one result appears per parent.
  3. Evaluate (//item)[last()] to verify the final node in the grouped result.
  4. Replace // with .// when the expression should stay inside a supplied component or container.

When debugging, temporarily remove [last()]. Seeing the full candidate list often reveals an incorrect parent, namespace, or filter long before the positional predicate is applied.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a page for documentation or visual inspection rather than query its DOM directly, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

One GET request returns PNG, JPEG, WebP, or PDF output:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for all options, including full-page lazy-image loading, CSS-selector element capture, device presets, custom viewport and retina scale, dark mode, PDF page settings, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage data, and the OpenAPI specification. Parameter names used by other screenshot APIs also work.

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo includes an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Does [last()] mean the last element in the source file?

No. It means the item at the final position of the current predicate context. Scope and grouping determine which nodes are in that context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I select the last child only if it has a class?

Use *[last()][contains(@class, 'name')] when the final child itself must pass the class test, or filter first with *[contains(@class, 'name')][last()] when you need the last child among all matching class elements.

Can I select the last element with CSS selectors instead?

CSS alone has no broadly supported standard selector equivalent to XPath’s document-order last(). A script can collect matching elements and index the final one, while XPath expresses the positional rule directly.

The Bottom Line

Use item[last()] for the last matching child in the current step, (//item)[last()] for the last item in a complete document result, and (.//item)[last()] for the last descendant in an explicit local scope. Apply content filters before [last()] when “last” should be calculated only among those filtered nodes.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.