Skip to main content

Crate xpath_eval

Crate xpath_eval 

Source
Expand description

§xpath-eval

A pure-Rust implementation of XPath 1.0 — parses an XPath expression and evaluates it against a document.

Generic and standalone — not tied to HTML, XML parsing, Schematron, or any specific document type. Callers provide their own parsed document via a trait; this crate only implements the XPath side (expression parsing, the data model view over the caller’s tree, and evaluation).

§Status

Implemented: the lexer/parser, the full location-path/predicate evaluation core (§2), and the complete XPath 1.0 Core Function Library (§4, all 27 functions, including id()). 147 tests pass, clippy and fmt are clean.

§Example

use xpath_eval::{Document, EvaluationContext, evaluate, parse};

// A caller brings their own tree, implementing `Node`/`Document` over it —
// this crate never parses or builds one itself. See `Node`'s doc comments
// for what each method must return.
let expr = parse("//item[@id='42']/name/text()")?;
let ctx = EvaluationContext::new(doc.root());
let result = evaluate(&expr, &ctx)?;
println!("{}", result.to_xpath_string());

EvaluationContext::new covers the common case (no variables, no namespace context). For XPath variables ($x) or prefixed name tests (p:foo) that need real namespace resolution, build an EvaluationContext directly and supply a variables/namespaces lookup hook — see their doc comments.

§Scope and known limitations

  • id() needs Node::is_id_attribute() to be overridden to do anything useful. The XPath 1.0 data model derives ID-ness from a DTD or schema; most Node implementations have no such information, so the trait’s default (false everywhere) means id() is a real function that simply never matches. Override is_id_attribute() on your Attribute-kind nodes if you know which attributes are IDs.
  • Namespace-prefix resolution requires a namespaces hook. Without one on EvaluationContext, a prefixed name test (p:foo) never matches any node — it does not fall back to guessing. Supply a resolver hook for spec-correct prefix→URI resolution.
  • following/preceding are full document-order axes (§2.3): each walk touches the potentially-large before/after portion of the whole tree, not just nearby nodes. Fine for typical documents; be aware of the cost on very large trees.
  • Implementing Node correctly requires document_order to be a genuine total order consistent with children()/attributes()/namespaces() — see the trait’s doc comments for the exact ordering rules (element before its namespace nodes before its attribute nodes before its children).

§Installation

[dependencies]
xpath-eval = "0.2"

§License

MIT — see LICENSE.

Structs§

EvaluationContext
The context an Expr is evaluated against (§2.2/§2.4): the context node, its 1-based proximity position and the context size within whatever node-set it was drawn from, a variable-binding lookup hook, and a namespace-prefix resolution hook.
ExpandedName
An expanded name (namespace URI + local name), §5.2/§5.3/§5.4/§5.5.
FilterExpr
[20] FilterExpr — a PrimaryExpr with zero or more predicates.
FunctionCall
[16] FunctionCall — name plus argument expressions. Not validated against the core function library in this phase; any syntactically valid QName is accepted.
LocationPath
[1]/[2]/[3] LocationPath — // is desugared into an explicit descendant-or-self::node() step prepended to (or inserted into) steps.
ParseError
A structured parse error: a byte offset into the input expression plus a human-readable description (not a bare string error).
QName
A qualified name (NCName (':' NCName)?, XML Namespaces §3).
Step
[4] Step — AxisSpecifier NodeTest Predicate*, with AbbreviatedStep (. / ..) desugared into the equivalent self/parent axis step.

Enums§

AdditiveOp
Axis
The 13 XPath axes ([6] AxisName). Abbreviated forms (@, ., ..) are represented as their equivalent explicit axis, not as a separate variant.
EqualityOp
EvalError
An evaluation-time error. Distinct from ParseError (parser.rs), which covers syntax — this covers semantic failures once a well-formed Expr is evaluated against a concrete context.
Expr
[14] Expr and the full operator-precedence chain [18]/[21]-[27] in a single flat enum: each precedence level either produces a node here or, when its operator is absent, simply returns the inner expression from the next-tighter level (standard precedence-climbing shortcut).
MultiplicativeOp
NodeKind
An XPath 1.0 node type (§5).
NodeTest
[7] NodeTest — includes the NameTest alternatives (*, prefix:*, QName) and the NodeType/processing-instruction(Literal) forms.
PathExpr
[19] PathExpr.
PrimaryExpr
[15] PrimaryExpr.
RelationalOp
Value
An XPath 1.0 value: one of the four object types (§3.1) — “node-set (an unordered collection of nodes without duplicates), boolean, number … [or] string”.

Traits§

Document
An XPath 1.0 document: gives access to the root node.
Node
A node in the caller’s tree, viewed as an XPath 1.0 data-model node.

Functions§

ancestor
ancestor axis (reverse): “contains the ancestors of the context node; … the parent of the context node and the parent’s parent and so on; thus, the ancestor axis will always include the root node, unless the context node is the root node”. Results are nearest-ancestor-first (reverse document order).
ancestor_or_self
ancestor-or-self axis (reverse): “contains the context node and the ancestors of the context node”. Results are context-node-first, then nearest ancestor first (reverse document order).
attribute
attribute axis: “contains the attributes of the context node; the axis will be empty unless the context node is an element”.
child
child axis: “contains the children of the context node”.
descendant
descendant axis: “contains the descendants of the context node; … thus the descendant axis never contains attribute or namespace nodes”.
descendant_or_self
descendant-or-self axis: “contains the context node and the descendants of the context node”.
evaluate
Evaluates expr against ctx, producing an XPath 1.0 value.
following
following axis: “contains all nodes in the same document as the context node that are after the context node in document order, excluding any descendants and excluding attribute nodes and namespace nodes”.
following_sibling
following-sibling axis: “contains all the following siblings of the context node; if the context node is an attribute node or namespace node, the following-sibling axis is empty”.
namespace
namespace axis: “contains the namespace nodes of the context node; the axis will be empty unless the context node is an element”.
parent
parent axis: “contains the parent of the context node, if there is one”.
parse
Parses an XPath 1.0 expression string into a structured Expr AST.
preceding
preceding axis (reverse): “contains all nodes in the same document as the context node that are before the context node in document order, excluding any ancestors and excluding attribute nodes and namespace nodes”.
preceding_sibling
preceding-sibling axis (reverse): “contains all the preceding siblings of the context node; if the context node is an attribute node or namespace node, the preceding-sibling axis is empty”. Results are nearest-preceding-sibling-first (reverse document order).
self_axis
self axis: “contains just the context node itself”.