Skip to main content

Crate oxml

Crate oxml 

Source
Expand description

§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 specialised at the other. quick-xml handles streaming and roxmltree provides read-only traversal. While xee targets XPath 3.1, earlier XPath 1.0 crates like sxd-xpath have not shipped releases since 2018.

oxml provides an integrated memory-safe toolkit combining a mutable arena DOM, XPath 1.0, and WebAssembly under one unified version.

§Quick Start

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");

§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 I/O, so no XXE — the crate contains no code that opens a file or a socket. An external entity is parsed, because the declaration is part of the grammar, and then expands to nothing unless the caller hands its text over through external::ExternalSource; the parser never fetches anything itself.

  • Entity expansion is bounded — internal entities are expanded, as XML requires, under a per-document budget (Limits::max_entity_expansion) and a nesting ceiling (Limits::max_entity_depth), so a billion-laughs document is rejected in microseconds rather than expanded.

  • Every limit is a field of Limits — depth, attribute count and size, name length, node and text counts, entity budgets, and the XPath expression budget. The defaults accept any document a person would write; Limits::strict is for input from the network.

  • 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.
  • libm — floating-point functions for xpath without std; required for a no_std build that keeps XPath.
  • async — [stream::AsyncReader] over tokio::io::AsyncRead. Implies std and adds tokio (with io-util and sync only).
  • tracing — tracing spans around parsing, evaluation, serialisation and streaming. Adds tracing with no default features.

Re-exports§

pub use error::Error;
pub use error::ErrorKind;
pub use error::Result;
pub use tree::Attribute;
pub use tree::Document;
pub use tree::ExpandedName;
pub use tree::NodeId;
pub use tree::NodeKind;
pub use xpath::FromXPath;xpath
pub use xpath::QueryError;xpath
pub use xpath::TypeError;xpath
pub use xpath::XPath;xpath
pub use xpath::XPathError;xpath

Modules§

encoding
Turning bytes into the &str the parser wants.
error
Errors, with source positions.
external
Content for external entities and subsets, supplied by the caller.
stream
Reading a document as a sequence of events, without building a tree.
tree
The document tree.
xpathxpath
XPath 1.0.

Structs§

Limits
Resource bounds applied while parsing.
SerialiseOptions
How a document should be written.

Enums§

Edition
Which edition of XML 1.0 to apply.
EmptyElement
How <a></a> with nothing inside is spelled.
Indent
One level of indentation.
Newline
The line ending between elements when indenting.
SerialiseError
Why a document cannot be written as XML that reads back as itself.

Constants§

MAX_DEPTH
The deepest element nesting the parser will accept.

Functions§

parse
Parse an XML document.
parse_bytes
Parse an XML document from bytes.
parse_bytes_with
Parse from bytes, decoding the encoding the document declares, under explicit resource bounds.
parse_with
Parse an XML document under explicit resource bounds.
parse_with_external
Parse with external content the caller supplies.