1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2026 oxml. All rights reserved.
//! # oxml
//!
//! A pure Rust XML toolkit. Zero unsafe code. Parsing, an ergonomic
//! tree, and `XPath` 1.0.
//!
//! ## Why this exists
//!
//! Rust's XML ecosystem is strong at one end and empty at the other.
//! `quick-xml` and `roxmltree` parse quickly; nothing maintained
//! offers what `lxml` gives Python. The only `XPath` crate,
//! `sxd-xpath`, has not shipped a release since 2018, and XSLT and
//! XSD validation have no pure-Rust implementation at all.
//!
//! oxml closes the query gap first, because that is the one people
//! actually hit.
//!
//! ## Quick Start
//!
//! ```
//! # #[cfg(all(feature = "xpath", feature = "std"))] {
//! use oxml::{parse, XPath};
//!
//! let doc = parse(r#"
//! <library>
//! <book lang="en"><title>Dune</title></book>
//! <book lang="fr"><title>Germinal</title></book>
//! </library>
//! "#).unwrap();
//!
//! let titles = XPath::compile("//book[@lang='en']/title").unwrap();
//! let found = titles.evaluate(&doc);
//!
//! assert_eq!(found.to_str(&doc), "Dune");
//! # }
//! ```
//!
//! ## Walking the tree directly
//!
//! `XPath` is optional. The tree stands on its own:
//!
//! ```
//! use oxml::parse;
//!
//! let doc = parse("<a><b id='1'>text</b></a>")?;
//! let root = doc.root_element().expect("a root element");
//!
//! assert_eq!(doc.element_name(root).unwrap().local, "a");
//!
//! let b = doc.children(root)[0];
//! assert_eq!(doc.attribute(b, "id"), Some("1"));
//! assert_eq!(doc.text(b), "text");
//! # Ok::<(), oxml::Error>(())
//! ```
//!
//! ## Design
//!
//! - **Zero `unsafe`** — `#![forbid(unsafe_code)]`, enforced at
//! compile time. The tree is an arena of index-addressed nodes, so
//! parent links cost no `Rc`, no `RefCell`, and no raw pointers.
//!
//! - **No entity expansion** — only the five predefined entities and
//! numeric character references are resolved. External and custom
//! entities are not, which forecloses XXE and billion-laughs by
//! construction rather than by configuration. A parser that cannot
//! expand them cannot be talked into leaking a file.
//!
//! - **Namespace-correct** — names compare by URI and local part,
//! never by prefix. An unprefixed *element* takes the default
//! namespace; an unprefixed *attribute* is in no namespace. That
//! asymmetry is the classic source of namespace bugs, so it is
//! explicit in the parser rather than assumed.
//!
//! ## Feature flags
//!
//! - `std` *(default)* — standard library integration, including
//! `std::error::Error`.
//! - `xpath` *(default)* — the `XPath` engine. Turn it off if you only
//! need to parse.
extern crate alloc;
extern crate std;
/// The README's examples, compiled as doctests.
///
/// `include_str!` rather than a copy: a snapshot of the README in a
/// test file drifts from the README the moment either is edited, and a
/// check that silently stops checking is worse than no check. This way
/// every ```rust block in the README is compiled and run by
/// `cargo test`, and a broken example fails the build.
/// Gated on the features the README demonstrates: its examples use
/// XPath, so under `--no-default-features` they would fail to compile
/// for a reason that says nothing about the crate.
;
/// The deepest element nesting the parser will accept.
///
/// Parsing descends one stack frame per open element, so an
/// arbitrarily deep document would exhaust the stack — and a stack
/// overflow aborts the process rather than unwinding, so no caller can
/// catch it. Documents come from the network in every one of this
/// crate's front ends, which makes that a denial of service rather
/// than a curiosity.
///
/// The limit is well above any hand-written document and far below the
/// depth that threatens the smallest stack a caller is likely to have
/// (test harnesses commonly give threads 2 MiB).
pub const MAX_DEPTH: usize = 256;
pub use ;
pub use parse;
pub use ;
pub use ;