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()needsNode::is_id_attribute()to be overridden to do anything useful. The XPath 1.0 data model derives ID-ness from a DTD or schema; mostNodeimplementations have no such information, so the trait’s default (falseeverywhere) meansid()is a real function that simply never matches. Overrideis_id_attribute()on yourAttribute-kind nodes if you know which attributes are IDs.- Namespace-prefix resolution requires a
namespaceshook. Without one onEvaluationContext, 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/precedingare 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
Nodecorrectly requiresdocument_orderto be a genuine total order consistent withchildren()/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§
- Evaluation
Context - The context an
Expris 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. - Expanded
Name - An expanded name (namespace URI + local name), §5.2/§5.3/§5.4/§5.5.
- Filter
Expr - [20]
FilterExpr— aPrimaryExprwith zero or more predicates. - Function
Call - [16]
FunctionCall— name plus argument expressions. Not validated against the core function library in this phase; any syntactically validQNameis accepted. - Location
Path - [1]/[2]/[3]
LocationPath—//is desugared into an explicitdescendant-or-self::node()step prepended to (or inserted into)steps. - Parse
Error - 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*, withAbbreviatedStep(./..) desugared into the equivalentself/parentaxis step.
Enums§
- Additive
Op - Axis
- The 13 XPath axes ([6]
AxisName). Abbreviated forms (@,.,..) are represented as their equivalent explicit axis, not as a separate variant. - Equality
Op - Eval
Error - An evaluation-time error. Distinct from
ParseError(parser.rs), which covers syntax — this covers semantic failures once a well-formedExpris evaluated against a concrete context. - Expr
- [14]
Exprand 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). - Multiplicative
Op - Node
Kind - An XPath 1.0 node type (§5).
- Node
Test - [7]
NodeTest— includes theNameTestalternatives (*,prefix:*,QName) and theNodeType/processing-instruction(Literal)forms. - Path
Expr - [19]
PathExpr. - Primary
Expr - [15]
PrimaryExpr. - Relational
Op - 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
ancestoraxis (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-selfaxis (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
attributeaxis: “contains the attributes of the context node; the axis will be empty unless the context node is an element”.- child
childaxis: “contains the children of the context node”.- descendant
descendantaxis: “contains the descendants of the context node; … thus the descendant axis never contains attribute or namespace nodes”.- descendant_
or_ self descendant-or-selfaxis: “contains the context node and the descendants of the context node”.- evaluate
- Evaluates
expragainstctx, producing an XPath 1.0 value. - following
followingaxis: “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-siblingaxis: “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
namespaceaxis: “contains the namespace nodes of the context node; the axis will be empty unless the context node is an element”.- parent
parentaxis: “contains the parent of the context node, if there is one”.- parse
- Parses an XPath 1.0 expression string into a structured
ExprAST. - preceding
precedingaxis (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-siblingaxis (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 selfaxis: “contains just the context node itself”.