JavaScript Document evaluate() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline Widely available
Instance method

What You’ll Learn

document.evaluate() is an instance method that runs an XPath expression and returns an XPathResult (see MDN Document: evaluate()). Learn the five parameters, common result types, how to iterate matches, how context nodes improve performance, when to prefer createExpression() or CSS selectors, and five try-it labs.

01

Kind

Instance method

02

Input

XPath string

03

Returns

XPathResult

04

Context

often document

05

Loop with

iterateNext()

06

Status

Baseline

Introduction

XPath is a query language for trees. With document.evaluate() you pass an XPath string plus a context node, and the browser returns an XPathResult — often a node iterator you walk with iterateNext().

MDN: XPath works on both HTML and XML documents. For everyday element picks, querySelector / querySelectorAll are usually clearer. Reach for evaluate() when you need XPath features (for example count(), axis-style paths, or XML-oriented queries).

💡
Think: CSS selectors’ powerful cousin

1) Write an XPath string
2) Pick a context node (often document)
3) Choose a result type (or use ANY_TYPE)
4) Read nodes with iterateNext() or value fields

Related tutorials: createExpression(), createNSResolver(), enableStyleSheetsForSet().

Understanding document.evaluate()

An instance method on the page’s document object (part of the XPathEvaluatorBase API on Document; MDN).

  • xpathExpression — string; the XPath to evaluate (MDN).
  • contextNode — node where the query is rooted; commonly document (MDN).
  • namespaceResolver — optional function for prefixes; null is common on HTML (MDN).
  • resultType — optional XPathResult type constant; default ANY_TYPE (0) (MDN).
  • result — optional existing XPathResult to reuse, or null for a new one (MDN).
  • Return value — an XPathResult linking to selected nodes or a scalar value (MDN).

📝 Syntax

General form of Document.evaluate (MDN):

JavaScript
evaluate(xpathExpression, contextNode, namespaceResolver, resultType, result)

Parameters

  • xpathExpression — a string representing the XPath to evaluate (MDN).
  • contextNode — the context node for the query. It is common to pass document (MDN).
  • namespaceResolver (optional) — a function that receives a namespace prefix and returns its URI. Use null for HTML or when no prefixes appear. Defaults to null if omitted (MDN).
  • resultType (optional) — integer for the XPathResult type. Defaults to ANY_TYPE (0) (MDN).
  • result (optional) — an existing XPathResult to fill, or null / omitted to create a new one (MDN).

Return value

An XPathResult. If result was null (or omitted), it is a new object; otherwise it is the same object you passed in (MDN).

Common resultType values (MDN)

ConstantValueUse for
ANY_TYPE0Whatever type the expression naturally produces (default)
NUMBER_TYPE1A single number (e.g. count())
STRING_TYPE2A single string
BOOLEAN_TYPE3A single boolean (e.g. not())
UNORDERED_NODE_ITERATOR_TYPE4All matching nodes; order not guaranteed
ORDERED_NODE_ITERATOR_TYPE5All matching nodes in document order
UNORDERED_NODE_SNAPSHOT_TYPE6Snapshot list; order not guaranteed
ORDERED_NODE_SNAPSHOT_TYPE7Snapshot list in document order
ANY_UNORDERED_NODE_TYPE8Any single matching node
FIRST_ORDERED_NODE_TYPE9First matching node in document order

MDN notes for iterators: they hold live references. Modifying the document can invalidate the iterator — iterating afterward may throw. Snapshots are not invalidated by DOM changes, but they may no longer match the live tree.

MDN example (find all h2 headings)

JavaScript
const headings = document.evaluate(
  "/html/body//h2",
  document,
  null,
  XPathResult.ANY_TYPE,
  null,
);

let thisHeading = headings.iterateNext();
let alertText = "Level 2 headings in this document are:\n";
while (thisHeading) {
  alertText += `${thisHeading.textContent}\n`;
  thisHeading = headings.iterateNext();
}
alert(alertText);

⚡ Quick Reference

GoalCode
Run XPathdocument.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null)
Iterate nodeswhile ((n = result.iterateNext())) { ... }
First node... FIRST_ORDERED_NODE_TYPE ...).singleNodeValue
Count nodes... NUMBER_TYPE ...).numberValue with count(...)
Scope to bodydocument.evaluate(".//h2", document.body, null, ...)
HTML namespacesPass null for namespaceResolver
MDN statusBaseline Widely available (since Jul 2015)

🔍 At a Glance

Four facts about document.evaluate().

Returns
XPathResult

object

Default type
ANY_TYPE

0

HTML resolver
null

common

Status
Baseline

since 2015

📋 Iterator vs snapshot results

Iterator types (4 / 5)Snapshot types (6 / 7)
How you readiterateNext()snapshotLength + snapshotItem(i)
DOM mutationCan invalidate the iterator (MDN)Snapshot stays; may be stale vs live DOM (MDN)
Best whenYou walk matches once without changing the treeYou need random access or will mutate the DOM

Examples Gallery

Examples follow MDN Document: evaluate() and practical beginner-friendly XPath patterns.

📚 Getting Started

Run XPath and walk matching nodes.

Example 1 — MDN: list all h2 headings

Evaluate a specific path and collect text with iterateNext().

JavaScript
const headings = document.evaluate(
  "/html/body//h2",
  document,
  null,
  XPathResult.ANY_TYPE,
  null,
);

const texts = [];
let node = headings.iterateNext();
while (node) {
  texts.push(node.textContent.trim());
  node = headings.iterateNext();
}
console.log(texts.join(" | "));
Try It Yourself

How It Works

MDN prefers a more specific path like /html/body//h2 over a bare //h2 on large documents, because the engine visits fewer unnecessary nodes.

Example 2 — Scope with document.body

MDN tip: start from a tighter context and use a relative path.

JavaScript
const headings = document.evaluate(
  ".//h2",
  document.body,
  null,
  XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  null,
);

const texts = [];
let node = headings.iterateNext();
while (node) {
  texts.push(node.textContent.trim());
  node = headings.iterateNext();
}
console.log(texts.join(", "));
Try It Yourself

How It Works

MDN: the leading . means “start from the context node” (document.body). Without it, //h2 would search from the document root again.

📈 Practical Patterns

Numbers, single nodes, and snapshot lists.

Example 3 — count() with NUMBER_TYPE

XPath can return a number instead of nodes.

JavaScript
const result = document.evaluate(
  "count(//button)",
  document,
  null,
  XPathResult.NUMBER_TYPE,
  null,
);

console.log(result.numberValue);
Try It Yourself

How It Works

MDN lists NUMBER_TYPE for expressions like count(). Read the value from result.numberValue. String and boolean types use stringValue / booleanValue.

Example 4 — First match with FIRST_ORDERED_NODE_TYPE

Grab a single node without iterating the whole set.

JavaScript
const result = document.evaluate(
  "//h2[@id='intro']",
  document,
  null,
  XPathResult.FIRST_ORDERED_NODE_TYPE,
  null,
);

const heading = result.singleNodeValue;
console.log(heading ? heading.textContent.trim() : "(not found)");
Try It Yourself

How It Works

MDN: FIRST_ORDERED_NODE_TYPE returns the first matching node in document order. Read it from singleNodeValue (or null if none).

Example 5 — Ordered snapshot list

Index into matches with snapshotItem — safer if you change the DOM.

JavaScript
const result = document.evaluate(
  "//li",
  document,
  null,
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null,
);

const texts = [];
for (let i = 0; i < result.snapshotLength; i++) {
  texts.push(result.snapshotItem(i).textContent.trim());
}
console.log(texts);
Try It Yourself

How It Works

Snapshots behave like a fixed list of matched nodes. MDN: changing the document does not invalidate the snapshot, but the list may become out of date relative to the live tree.

🚀 Common Use Cases

  • One-off XPath queries — run a path without compiling an expression first.
  • XML / mixed documents — namespace-aware selection with a resolver.
  • Numeric / boolean XPathcount(), not(), and similar.
  • Scoped searches — pass a panel or document.body as context.
  • Legacy tooling — scripts and tests that already speak XPath.
  • Not every UI query — prefer CSS selectors for simple HTML picks.

🧠 How evaluate() Works

1

Pass XPath + context

MDN: provide the expression string and a context node (often document).

Input
2

Resolver + result type

Use null for HTML namespaces; pick ANY_TYPE or an explicit type.

Options
3

Get XPathResult

A new result object (or the one you reused via the result parameter).

Run
4

Read matches or values

Iterate nodes, use singleNodeValue, or read numberValue / string / boolean.

📝 Notes

  • MDN: Baseline Widely available since July 2015.
  • MDN: works on both HTML and XML documents.
  • MDN: pass null for namespaceResolver on typical HTML pages.
  • MDN: prefer specific paths and tight contexts over a bare // on large trees.
  • Do not mutate the DOM while walking an iterator without understanding invalidation (MDN).
  • Related: createExpression(), createNSResolver(), parseHTML().

Browser Support

Document.evaluate() is Baseline Widely available on MDN (since July 2015). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline Widely available

Document.evaluate()

Run XPath expressions against HTML and XML documents across all major browsers.

Baseline Widely available
Google Chrome Supported
Yes
Mozilla Firefox Supported
Yes
Apple Safari Supported
Yes
Microsoft Edge Supported
Yes
Opera Supported
Yes
Internet Explorer Supported (legacy)
Yes
evaluate() Wide

Bottom line: Use document.evaluate for one-shot XPath. Prefer createExpression for reuse, and querySelector for simple HTML selection.

Conclusion

document.evaluate(xpath, context, null, type, null) runs an XPath query and returns an XPathResult. Use iterators for a one-pass walk, snapshots when you need indexed access, and scalar types for count()-style expressions — exactly the toolkit MDN documents.

Continue with createExpression(), execCommand(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Pass null for the namespace resolver on plain HTML (MDN)
  • Use a tighter contextNode and relative .// paths (MDN)
  • Pick an explicit result type when you know you need nodes vs numbers
  • Prefer snapshots if you will mutate the DOM while reading matches
  • Compile with createExpression when the same path runs many times

❌ Don’t

  • Reach for XPath when a simple CSS selector is enough
  • Rely on a bare // path on huge documents without considering cost (MDN)
  • Mutate the tree while iterating without knowing invalidation rules (MDN)
  • Forget singleNodeValue can be null when nothing matches
  • Skip a namespace resolver when your XPath uses prefixes

Key Takeaways

Knowledge Unlocked

Five things to remember about evaluate()

Run XPath once; read an XPathResult.

5
Core concepts
🔄02

Loop

iterateNext()

nodes
📄03

Context

often document

or body
04

Reuse?

createExpression

compile
🛡05

Status

Baseline

2015

❓ Frequently Asked Questions

MDN: Document.evaluate() selects nodes (or other values) based on an XPath expression. It works on both HTML and XML documents.
No. MDN marks Document.evaluate() as Baseline Widely available (since July 2015). It is not Deprecated, Experimental, or Non-standard.
An XPathResult. If you pass null (or omit) for the result parameter, you get a new XPathResult. If you pass an existing XPathResult, that same object is reused and returned (MDN).
MDN: null is common for HTML documents or when no namespace prefixes are used. If omitted, it defaults to null.
Use document.createExpression() when you will run the same XPath many times. For a one-off query, document.evaluate() is often enough.
MDN notes that more specific paths (for example /html/body//h2) and a tighter contextNode often perform better than a bare // shortcut on large documents.
Did you know?

MDN’s xml:id helper uses document.evaluate with a tiny namespace resolver that always returns the XML namespace URI — a handy pattern when attribute names carry a prefix and CSS selectors are not enough.

Next: execCommand()

Learn the deprecated non-standard API for legacy rich-text and clipboard commands.

execCommand() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful