[!NOTE] The rewrite has landed. Schema parsing, structural validation, simple types with restriction facets, and
xs:patternall work; see Status for exactly what is and is not supported.
0.0.1on crates.io is the old crate, which exposed no public API at all. Do not use it.
Contents
Getting started
Reference
- Why this crate exists — the gap it fills
- The oxml ecosystem — where this fits
- Ecosystem comparison — XSD support in Rust
- Planned capabilities — the roadmap
Practical
Status
| State | |
|---|---|
| Schema parsing | ✅ elements, sequence, choice, cardinality, attributes |
| Simple types | ✅ nine built-ins, nine restriction facets |
xs:pattern |
✅ own engine, XSD dialect |
| Diagnostics | ✅ every violation, each with a path |
| Tests | ✅ 27 |
xs:all |
✗ |
xs:import / include |
✗ |
| Identity constraints | ✗ |
| Complex-type derivation | ✗ |
An unsupported construct is skipped rather than rejected: the
surrounding rules still apply, so a schema using xs:all validates
everything else correctly instead of failing wholesale.
Install
[]
= { = "https://github.com/sebastienrousseau/xmlschema" }
= { = "https://github.com/sebastienrousseau/oxml" }
Published releases follow once the suite cuts its first version together.
Quick Start
use ;
let xsd = r#"
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
</xs:sequence>
<xs:attribute name="lang" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
"#;
let schema = parse_schema?;
let doc = parse?;
assert!;
# Ok::
Every violation is reported, each with a path:
/invoice/issued — `22/08/2026` is not a valid date (YYYY-MM-DD)
/invoice/line[1]/@currency — `pounds` does not match the pattern `[A-Z]{3}`
/invoice/line[1]/amount — -5 must be greater than 0
/invoice/line[2] — missing required attribute `currency`
/invoice/line[2]/amount — `not a number` is not a valid decimal
Why this crate exists
Rust has no pure-Rust XSD validator. The options today are:
libxml— bindings to libxml2. Complete and battle-tested, but it is C: it needs a build toolchain, containsunsafe, does not work in WebAssembly, and inherits libxml2's CVE stream.- Nothing else. There is no maintained pure-Rust implementation.
For a project already committed to safe Rust — no C toolchain, WASM targets, an auditable dependency tree — that is not a choice so much as an absence.
xmlschema exists to close it, with the same constraints as the rest
of the suite: #![forbid(unsafe_code)], no FFI, no C.
The oxml ecosystem
Every member ships the same version number, so there is never a compatibility table to consult.
| Crate | What it is | Status |
|---|---|---|
oxml |
Core — parser, tree, XPath 1.0 | Available |
oxml-cli |
Command-line querying and formatting | Planned |
oxml-lsp |
Language server | Planned |
oxml-mcp |
Model Context Protocol server | Planned |
oxml-wasm |
WebAssembly bindings | Planned |
xmlschema |
XSD validation | Being rewritten |
This crate keeps its published name rather than being folded into
oxml. The name means XSD validation specifically, and repurposing it
into a general toolkit would have handed existing users something
entirely different under a name they already depend on.
Ecosystem comparison
| Crate | XSD validation | Pure Rust | WASM | Last release |
|---|---|---|---|---|
xmlschema |
planned | ✅ | ✅ | 2023 (unusable) |
libxml |
✅ | ✗ (C-FFI) | ✗ | active |
quick-xml |
✗ | ✅ | ✅ | active |
roxmltree |
✗ | ✅ | ✅ | active |
xot |
✗ | ✅ | ✅ | 2025 |
Planned capabilities
In order:
- Schema parsing — read an
.xsdinto a usable model, built onoxml's tree. - Structural validation — elements, attributes, cardinality, sequence/choice/all.
- Simple type validation — the built-in datatypes, restrictions, patterns, enumerations.
- Complex types — extension, restriction, mixed content.
- Diagnostics — every violation reported with an element path and a reason, so a caller can fix all of them in one pass rather than probing one failure at a time.
Import mechanisms (xs:import, xs:include, xs:redefine) come after
the core is correct, because they multiply the surface without adding
validation power.
Development
Security
XSD validation is normally applied to untrusted documents, which makes
the parser's threat model part of this crate's threat model. It
inherits oxml's posture:
- No entity expansion. Only the five predefined entities and numeric character references are resolved, so XXE and billion-laughs are foreclosed by construction rather than by a flag.
- No
unsafe.#![forbid(unsafe_code)], enforced at compile time.
Report vulnerabilities privately — see SECURITY.md.
Documentation
Acknowledgements
- libxml2 — the reference implementation, and the yardstick for behaviour.
- W3C — for the XML Schema specification.
- python-xmlschema — proof that a readable, standalone XSD implementation is achievable.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.