oxml/xpath/ast.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2026 oxml. All rights reserved.
3
4//! The `XPath` expression tree.
5
6use alloc::boxed::Box;
7use alloc::string::String;
8use alloc::vec::Vec;
9
10/// Which direction and which nodes a step selects.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum Axis {
13 /// `child::` — the default axis.
14 Child,
15 /// `descendant::`
16 Descendant,
17 /// `descendant-or-self::` — the `//` shorthand.
18 DescendantOrSelf,
19 /// `parent::`
20 Parent,
21 /// `ancestor::`
22 Ancestor,
23 /// `ancestor-or-self::`
24 AncestorOrSelf,
25 /// `self::` — the `.` shorthand.
26 SelfAxis,
27 /// `attribute::` — the `@` shorthand.
28 Attribute,
29 /// `following-sibling::`
30 FollowingSibling,
31 /// `preceding-sibling::`
32 PrecedingSibling,
33}
34
35/// What a step matches once the axis has produced candidates.
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub enum NodeTest {
38 /// `*` — any element (or any attribute on the attribute axis).
39 Wildcard,
40 /// A local name, matched ignoring namespace.
41 Name(String),
42 /// `text()`
43 Text,
44 /// `comment()`
45 Comment,
46 /// `node()` — anything at all.
47 Any,
48}
49
50/// One location step: an axis, a test, and zero or more predicates.
51#[derive(Debug, Clone, PartialEq)]
52pub struct Step {
53 /// The axis to walk.
54 pub axis: Axis,
55 /// The test applied to each candidate.
56 pub test: NodeTest,
57 /// Predicates, applied left to right.
58 pub predicates: Vec<Expr>,
59}
60
61/// An `XPath` expression.
62#[derive(Debug, Clone, PartialEq)]
63pub enum Expr {
64 /// A location path. `absolute` means it started with `/`.
65 Path {
66 /// Whether the path starts at the document root.
67 absolute: bool,
68 /// The steps, in order.
69 steps: Vec<Step>,
70 },
71 /// A literal string.
72 Literal(String),
73 /// A literal number.
74 Number(f64),
75 /// A binary operation.
76 Binary {
77 /// The operator.
78 op: BinaryOp,
79 /// Left operand.
80 lhs: Box<Expr>,
81 /// Right operand.
82 rhs: Box<Expr>,
83 },
84 /// A function call.
85 Function {
86 /// The function's name.
87 name: String,
88 /// Its arguments.
89 args: Vec<Expr>,
90 },
91 /// Unary negation.
92 Negate(Box<Expr>),
93}
94
95/// A binary operator.
96#[derive(Debug, Clone, Copy, PartialEq, Eq)]
97pub enum BinaryOp {
98 /// `=`
99 Eq,
100 /// `!=`
101 Ne,
102 /// `<`
103 Lt,
104 /// `<=`
105 Le,
106 /// `>`
107 Gt,
108 /// `>=`
109 Ge,
110 /// `and`
111 And,
112 /// `or`
113 Or,
114 /// `+`
115 Add,
116 /// `-`
117 Sub,
118 /// `*`
119 Mul,
120 /// `div`
121 Div,
122 /// `mod`
123 Mod,
124 /// `|` — node-set union.
125 Union,
126}