The static evaluation context (XPath 2.0 §2.1.1) — the config that
is fixed for the whole evaluation and travels by reference so it
can’t be lost or duplicated. Holds exactly the knobs that don’t
vary within an evaluation; genuinely dynamic state (context item,
position, the [xsl:]default-collation that nests via
Expr::WithDefaultCollation) lives elsewhere.
One typed atomic value — the carrier for XPath 2.0 schema-aware
semantics. Holds the XSD type (kind, the local name of the
XSD primitive or derived type as a &'static str from the
finite type table), the lexical form, plus pre-computed numeric
/ boolean views when the type permits them.
A structural event emitted by parse_json_events. Lets a
consumer build either the XDM map/array Value (fn:parse-json)
or the F&O JSON element vocabulary (fn:json-to-xml) from one
parser. Number carries the raw lexical so json-to-xml can
preserve the input’s number representation.
Number-to-string flavour — the serialization slice of the static
context. Xpath10 is XPath 1.0 §4.2 decimal-only, Libxml2 is
libxml2’s 1.23e+19 form, Xpath20 is the F&O §17.1.2 scientific
form (1.0E6) for xs:double/xs:float. xs:integer /
xs:decimal are decimal in every style, so integer output never
changes; only doubles/floats vary.
In-scope [xsl:]default-collation URI as resolved at the
surrounding XSLT element when the current XPath expression
was compiled. The XSLT eval pushes the URI before each
xpath_eval call so XPath operators (eq, ne, lt, …)
can fold string operands per the static collation context
without threading the URI through every comparison. Default
None denotes the codepoint collation (no fold).
Cap on the number of charged “steps” any single XPath evaluation
may perform. Nested-predicate expressions like
//*[.=//*[.=//*[.=…]]] have N^k complexity in document size N
and predicate-nesting depth k — easily minutes-to-hours of CPU
on adversarial input (found by the fuzz_xpath_eval target).
Caller-supplied resolver for things outside the XPath spec that
downstream consumers (libxslt, lxml’s extensions= / variables=
/ namespaces= kwargs) want to inject:
Filter nodes by sequentially applying each predicate. Each
per-node sub-context inherits the surrounding compat flag so
predicate-internal calls to string() / number() / etc. observe
the same libxml2-compat behaviour as the outer expression.
Resolve an XSD type local name to a stable &'static str. Used
by the xs: constructor dispatch and the cast/instance-of paths
so the kind tag costs zero allocation.
Cast a value to an atomic sequence type. Any failure to convert
the lexical value to the target type is a dynamic error
err:FORG0001 (F&O §17.1); the _impl body reports the specific
failing form and this wrapper attaches the spec code (without
overwriting a more specific code an inner step may have set).
Convert an xs:date / xs:dateTime / xs:time lexical to a
signed microsecond count after timezone normalisation. A missing
timezone is treated as UTC (XPath 2.0 §10.4 implementation-defined
implicit timezone — we pick UTC for stability across runs).
Returns None when the lexical doesn’t parse.
XSLT 2.0 §16.5.1 cardinal / ordinal word presentation for
numeric format markers. English-only — the spec is
locale-dependent and the W3C conformance suite exercises only
the 'en' language for the bare W / w / Ww modifiers.
Negative inputs fall through to the decimal form (rare in
date/time contexts).
Evaluate a single XPath step against a node-set, returning the
post-predicate result. compat propagates the surrounding
XPathContext’s libxml2-compat flag into
the per-predicate eval contexts this function constructs. Callers
outside the engine (the sup-xml-compat C ABI shim) generally
pass false.
Convenience for callers that just need the boolean value of an
expression evaluated against a fresh context (context node passed
in, position 1 of 1, no libxml2-compat tweaks). Used by the XSD
1.1 assertion evaluator — see crate::xsd.
True iff e syntactically references the context item (.
or self::* axis steps anywhere within). Used to decide
whether an expression can be hoisted out of a per-item loop.
Conservative: returns true on anything that might read .,
so the fast path bails to the safe slow path in ambiguous
cases.
Reduce a value to the single atomic value usable as a map key
(XPTY0004 if not a singleton atomic; lenient — first item, nodes
contribute their string value).
Serialize a number under an explicit NumStyle. Doubles/floats
take scientific form only under Xpath20; everything else is
decimal (or libxml2’s form under Libxml2). Exposed so the XSLT
result serializer can render a Value::Number directly under the
stylesheet’s style without rebuilding a Value.
True iff evaluation is currently inside an XPath 1.0 backwards-
compatibility scope. Exposed for the XSLT layer so spec-checks
that loosen in BC mode (e.g. xsl:sort’s XTTE1020 cardinality
rule) can probe the current scope without duplicating the
thread-local plumbing.
Validate and read a boolean-typed JSON option (F&O §17.5): the value
must be exactly one xs:boolean. Absent → Ok(None); wrong
type/cardinality → FOJS0005.
Test node against test as if reached on the child:: axis
(principal node kind = element). Exposed for the XSLT pattern
matcher, which handles document-node(element(N)) patterns
structurally and needs to check the document element against the
inner element test.
XSD type-hierarchy lookup — parent of a derived type per
XML Schema Part 2 §3. Returns None when t is unknown or is
already anyType (the universal supertype). The chain bottoms
out at anyAtomicType ⊂ anySimpleType ⊂ anyType.
Parse json (F&O §17.5), driving sink with one JsonEvent per
structural token. Duplicate-key policy is left to the consumer —
the parser reports keys verbatim. escape keeps backslash
sequences in string content; liberal tolerates unescaped control
characters.
Parse text to the XDM representation (F&O §17.5): object → map,
array → array, string → xs:string, number → xs:double, true/false →
xs:boolean, null → empty sequence. duplicates is one of
reject / use-first / use-last. Public so the XSLT layer’s
fn:json-doc can reuse it after loading the resource.
Reseed the stable current-instant for a new execution scope (called
at XSLT-transform entry and at each top-level XPath evaluation), so
the next fn:current-* call samples a fresh time while remaining
stable for the rest of that scope.
Reset the remaining-step counter to this thread’s configured budget
for a fresh top-level evaluation. Called by
super::XPathContext::eval_with; XSLT-internal eval call sites
inherit the current budget (in practice the default, since
stylesheets don’t pathologically nest and an untrusted-XPath caller
goes through XPathContext).
RFC 3986 §5.3 reference resolution. Combine base (treated as
already absolute) and rel (a possibly-relative URI reference)
into an absolute URI string. Implements the strict form: a
rel with its own scheme returns essentially unchanged (with
dot-segments removed), matching fn:resolve-uri’s spec.
Set this thread’s per-evaluation step ceiling. Takes effect on the
next reset_eval_budget (i.e. the next top-level evaluation).
Lower it when evaluating untrusted XPath to cap worst-case CPU;
raise it for trusted, legitimately-expensive generated expressions.
A value of 0 makes every evaluation fail on its first step.
Wrap a lexical string as a Value::Typed of a non-numeric,
non-boolean built-in XSD type — the carrier for F&O functions whose
return type is a specific atomic type (fn:base-uri → xs:anyURI,
fn:local-name-from-QName → xs:NCName). Returning a typed value
(not a bare Value::String) is what makes instance of answer
correctly per XPath 2.0 §3.10.2.
Walk the expression AST checking that every namespace prefix used
in a name test (prefix:local, prefix:*) resolves through the
supplied bindings. Surfaces an XPathEvalError for the first
unbound prefix encountered, matching libxml2’s
XPATH_UNDEF_PREFIX_ERROR.
A canonical key for value-equality grouping/distinct (XSLT 2.0
§14.3 group-by uses the eq operator). Returns Some only for
the typed values whose eq semantics differ from their lexical
string: temporal values normalise to a UTC instant (so two
dateTimes in different time zones for the same instant share a
key), durations to their total magnitude. None for everything
else — the caller uses the string-value, which already matches
eq for strings / numbers / booleans.
Serialize v to its string-value under an explicit NumStyle.
This is the entry point for callers that know their static context
(notably the XSLT result serializer, which must render an
xs:double in F&O scientific form even though the value itself no
longer carries a precomputed lexical).
Set item as the current atomic context item for the duration
of f, restoring the previous value on return (including on
panic via RefCell’s borrow). None clears the slot — useful
when stepping into a sub-expression whose . should fall back
to the node-based context.
Run f with uri installed as the in-scope default-collation
URI, restoring the previous value on return (including on
panic). Caller is responsible for picking the right URI from
the compiled expression’s static context.
Set whether the focus (context item / position / size) is
undefined for the duration of f. Restored on return. XSLT 2.0
§10.3 uses this around xsl:function bodies.
Opaque foreign-doc node pointer. Pointer identity is meaningful
(used for set dedup); the engine never dereferences this directly
for tree navigation — that goes through the XPathBindingseval_steps_in_foreign_doc / foreign_string_value callbacks,
which the compat layer implements by routing through the loaded
doc’s DocIndex. Reads of structural fields like kind/children
here are sound because foreign docs always come from our own
parser (libxml2-ABI-compatible Node layout, lifetime-managed by
the doc registry on XPathBindings).