Skip to content
StAX-XML

Converter - XPath Guide

The converter accepts a deliberately small XPath-shaped selector language that can be evaluated while XML tokens stream through the reader. It does not build a DOM or fall back to a general XPath 1.0 tree evaluator.

Form Example Meaning
Absolute path /catalog/book/title Match a path from the document root.
Leading descendant //book/title Match the path below any book element. // is supported only at the beginning.
Relative path ./title Match below the object or array item’s current element.
Current element . Select the current contextual element.
Attribute terminal ./@id Read an attribute from the selected element.
Direct text terminal ./text() Capture direct text on the selected element.
Positive position /catalog/book[2]/title Match one 1-based sibling position.
import { x } from 'stax-xml/converter';
const catalog = x.object({
books: x.array(
x.object({
id: x.string('./@id'),
title: x.string('./title'),
}),
'/catalog/book',
),
});
const value = catalog.parseSync(xml);

Selectors are compiled and cached automatically. Call .precompile() only to warm that work before the first parse; there is no public .compile() step.

For example, a server can move the one-time IR lowering and executor creation out of its first request by warming shared schemas in its startup module:

export const catalogSchema = x.object({
title: x.string('/catalog/title'),
}).precompile();
// Request handlers still call the normal API.
const catalog = catalogSchema.parseSync(requestBody);

This is a latency-placement choice, not a faster steady-state mode. Skip it unless first-request latency matters, and reuse the schema instance rather than rebuilding it per request. Parse options remain per-parse settings and are not part of warm-up.

Names are matched as the qualified names present in the XML stream. A selector such as /p:catalog/p:item matches those exact prefixed names. The converter does not accept a separate prefix-to-URI binding option, so changing the XML prefix changes the selector that must be used. Unprefixed selectors match unprefixed XML names.

Wildcards, nested //, arbitrary predicates, axes, unions, variables, operators, and XPath functions other than terminal text() are not part of the public converter contract. Unsupported syntax throws during schema construction, before .precompile() or parsing, instead of materializing a document tree.

For unknown or dynamic XML, use EventReader / EventReaderSync. Use StreamReader / StreamReaderSync when current-token traversal and lower allocation are more important than stable event objects.

See the conformance matrix for the exact boundary.