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.

Wrap the XPath expression that selects your matches in count(). For example, count(//item) returns the number of item elements selected from the document context. Use count(.//item) when the starting point is the current element, and add predicates inside the path when you need a narrower count.

The basic pattern: count the result of a selection

XPath separates selecting values from counting them. A path such as //item selects matching elements. Passing that path to count() evaluates the selection and returns a number:

count(//item)

If the document contains seven matching elements, the result is the numeric value 7. The function does not return the elements themselves, and it does not alter the selection.

Common count expressions

Expression What it counts
count(//item) Every item selected from the document context
count(.//item) item descendants below the current context node
count(//item[@status='open']) Matching item elements whose status attribute is open
count(item) Child elements named item, when evaluated with the parent as context

The result is numeric: in XPath 1.0 it is an XPath number, while later XPath versions specify an integer count of sequence items.

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

Why context changes the number

The same-looking name test can produce different totals depending on where evaluation starts. //item is shorthand for a search through descendants of the document context. By contrast, .//item begins at the current context node and searches only its descendants.

Suppose the document has two section elements, each containing three item elements. Evaluated against the whole document, count(//item) returns 6. Evaluated while the first section is the current node, count(.//item) returns 3.

This distinction matters in XSLT templates, test tools, browser automation, and XML APIs that evaluate one expression repeatedly for different context nodes. If a count is unexpectedly large, verify whether the expression starts at the document or at the current element.

Document versus current-node examples

count(//item)       (: all matching items in the document context :)
count(.//item)      (: matching descendants of the current node :)
count(item)         (: matching child elements of the current node :)

The comment syntax shown above is XPath 2.0-and-later syntax. In an XPath 1.0 host, use the expressions without inline comments.

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

Count is not the same as position or last

Three functions are often confused:

Function Question answered
count(expression) How many nodes or items does this expression return?
last() How many entries are in the current context list?
position() Which position is the current item in that context list?

For example, inside a predicate evaluated over a set of nodes, position() = last() tests whether the current node is the final one in that context. It does not count an arbitrary path elsewhere in the document. To obtain the total number of matches for a path, use count(path).

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

Predicates: filter first, then count

Put conditions inside the argument to count(). This makes the number describe exactly the nodes that satisfy the condition.

count(//item[@status='open'])
count(//book[@category='technical'])
count(//a[@href])
count(//row[price > 100])

A frequent error is adding [1] and expecting a total. In a path step, [1] filters that step to one node according to its context ordering. Therefore:

count(//item[1])

counts the nodes retained by that predicate, commonly one matching item per relevant step, rather than all item elements. To count every match, omit [1]. If you really want to count the first node selected by an entire path, group the path before applying the positional predicate where your XPath version and host support that syntax, then recognize that the resulting count can only be zero or one.

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

XPath versions: what exactly is being counted?

XPath 1.0

The W3C XPath 1.0 Recommendation (16 November 1999) defines count(node-set) as the number of nodes in its argument node-set. A node-set contains nodes selected from the XML tree; duplicate references do not turn into duplicate nodes in the node-set.

XPath 2.0

The W3C XPath 2.0 Second Edition (14 December 2010) uses a sequence data model. A sequence can contain zero or more items, including nodes and atomic values. This permits expressions such as:

count((1, 2, 3))

The result is three because the sequence has three items, even though none is an XML node.

XPath 3.1

XPath 3.1 (21 March 2017), together with the Functions and Operators specification, defines fn:count($arg as item()*) as xs:integer. It returns the number of items and returns 0 for an empty sequence:

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

Do not infer a host’s version from a product name alone. Check the documentation for the browser, XML library, transformation processor, or test runner that evaluates your expression. XPath 1.0 syntax is the conservative choice only when the host explicitly documents XPath 1.0.

Nodes, atomic values and “selections”

“Selection” is informal shorthand. An XPath expression can return nodes, a number, a string, a Boolean, or (in XPath 2.0 and later) a sequence containing permitted items. Thus //item selects nodes, while count(//item) evaluates to a number. A tool may show the node list in one pane and the numeric result in another because its host API exposes result types differently.

Namespaces: the invisible reason for a zero

Element names in XPath are resolved through the expression’s namespace context. If an XML document uses a default namespace, a bare test such as //item may match nothing in many APIs, even when the serialized document visibly contains <item>.

Bind a prefix to the document’s namespace URI in the host’s XPath context, then use that prefix:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
count(//p:item)

The exact prefix-binding code is application-specific; XPath standards define the expression semantics, not every host API’s setup procedure. When a count is zero unexpectedly, inspect the namespace URI and the namespace bindings supplied to the evaluator.

Why an XPath count can look wrong

  • Wrong context: //item searches from the document context, while .//item is relative to the current node.
  • Unexpected predicate scope: A predicate such as [1] limits a path step before counting.
  • Namespace mismatch: The document’s elements belong to a namespace that your expression did not bind.
  • Version mismatch: Sequence syntax from XPath 2.0 or 3.1 may not be accepted by an XPath 1.0 engine.
  • Result exposure: The host application may convert, display, or wrap the returned number according to its own API.
  • Different input tree: HTML parsers can repair markup and construct a tree that differs from the source text; count the parsed tree actually supplied to XPath.

A practical debugging procedure

  1. Evaluate the unwrapped path, such as //item, and inspect which nodes the host reports.
  2. Wrap the exact same path in count(); do not change predicates while diagnosing.
  3. Replace // with .// only after confirming the intended context node.
  4. Check every predicate, especially positional predicates such as [1] and conditions involving attributes.
  5. Identify the XPath version documented by the host and remove unsupported sequence syntax if it is an XPath 1.0 engine.
  6. Check namespace bindings against the document’s namespace declarations.
  7. Confirm how the host API returns numeric results and whether it is displaying a conversion rather than the raw XPath value.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance and reliability considerations

Counting requires evaluating the argument expression. A broad descendant search such as //item can examine much more of a large tree than a path anchored to a known container. If you already have a context element, prefer a relative expression such as count(.//item); if the structure is known, use a more specific path such as count(/catalog/section/item). Filter in the XPath expression so the evaluator does not return a large node list that your host must count afterward.

Standards specify the result, not a universal execution time or memory cost. Performance depends on the host implementation, document size, parser, indexes, and whether the expression is evaluated repeatedly. In a loop, avoid re-running a document-wide count when one calculation can be reused safely.

Or skip the browser setup

If your XPath work begins with collecting pages to inspect, ScreenshotNeo can capture a URL through one HTTP request instead of requiring your own browser automation setup. It is a website screenshot API and MCP server for developers; the API can return PNG, JPEG, WebP, or PDF.

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

For a complete parameter list, see the ScreenshotNeo documentation. A cURL request is:

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

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}`);

Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Does count() count matching attributes as well as elements?

Only if the expression selects those attributes. For example, count(//item/@status) counts selected status attributes, while count(//item) counts item elements.

What does count() return for no matches?

It returns zero: an empty node-set in XPath 1.0 and an empty sequence in XPath 2.0 and later both produce a count of 0.

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

Can I use count() to test whether anything exists?

Yes, a comparison such as count(path) > 0 yields a Boolean, but use the host’s supported existence or Boolean expression when you only need an existence test rather than the numeric total.

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.