Skip to content

Commit ca3b923

Browse files
committed
release: prepare 0.4.0 with Schematron, XPath matches(), XSD elementFormDefault
Headline features: - ISO Schematron validation (parse, validate, phases, variables, firing rules) - XPath matches() regex function for pattern validation - XPath namespace-aware name matching via set_namespace() - XSD elementFormDefault="qualified" support - WASM/Python validation APIs (RelaxNG, XSD, Schematron) - xmllint --schematron CLI flag - fuzz_schematron fuzz target Bug fixes: - XPath attribute paths returning String instead of NodeSet - XPath prefix:* tokenization - Schematron message interpolation for NodeSets
1 parent 0ba7d5d commit ca3b923

4 files changed

Lines changed: 59 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,60 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.4.0] - 2026-03-14
9+
10+
### Added
11+
12+
- **ISO Schematron validation** (`validation::schematron` module) — rule-based XML
13+
validation per ISO/IEC 19757-3, complementing DTD, RelaxNG, and XSD
14+
- `parse_schematron()` / `validate_schematron()` / `validate_schematron_with_phase()` API
15+
- Assert/report checks with `XPath`-driven test expressions
16+
- Firing rule semantics (first matching rule wins per pattern)
17+
- Three-level `<sch:let>` variables (schema, pattern, rule scope)
18+
- Message interpolation via `<sch:value-of select="..."/>`
19+
- Phase-based selective validation (`<sch:phase>` / `<sch:active>`)
20+
- Dual namespace support: ISO (`http://purl.oclc.org/dml/schematron`) and
21+
classic 1.5 (`http://www.ascc.net/xml/schematron`), plus `sch:` prefix
22+
- 31 unit tests + 11 integration tests with realistic purchase order schema
23+
- **`xmllint --schematron`** — CLI validation against Schematron schemas, following
24+
the existing `--relaxng` and `--schema` patterns
25+
- **XPath `matches()` function** — regex matching for Schematron pattern validation,
26+
with a hand-rolled engine (no `regex` crate dependency) supporting character classes,
27+
quantifiers, shorthand (`\d`, `\s`, `\w`), alternation, grouping, counted
28+
quantifiers `{n,m}`, and flags (`i`, `s`)
29+
- **XPath namespace-aware name matching**`XPathContext::set_namespace()` registers
30+
prefix→URI bindings so that prefixed name tests like `//inv:invoice` resolve via
31+
namespace URI comparison instead of string matching; Schematron `<sch:ns>` bindings
32+
are automatically threaded through
33+
- **XSD `elementFormDefault` support** — when set to `"qualified"`, child elements
34+
in instance documents must carry the schema's target namespace; fixes namespace
35+
validation for UBL 2.4 and similar schemas
36+
- **WASM validation APIs**`validateRelaxng()`, `validateXsd()`,
37+
`validateSchematron()` on `WasmDocument`, returning `WasmValidationResult`
38+
with `isValid`, `errors`, and `warnings`
39+
- **Python validation APIs**`validate_relaxng()`, `validate_xsd()`,
40+
`validate_schematron()` on `Document`, returning `ValidationResult` with
41+
`is_valid`, `errors`, `warnings`, and `__bool__()` support
42+
- `fuzz_schematron` fuzz target for schema parsing and validation (11 total)
43+
44+
### Fixed
45+
46+
- **XPath attribute path returning String instead of NodeSet** — multi-step paths
47+
ending with an attribute axis (e.g., `item/@amount`) now correctly return a
48+
`NodeSet`, fixing `sum()`, `count()`, and comparison operations on attribute
49+
collections
50+
- **XPath `prefix:*` tokenization** — the lexer now correctly tokenizes namespace
51+
wildcard expressions like `inv:*` as a single token instead of failing with a
52+
parse error
53+
- **Schematron message interpolation for NodeSets**`<sch:value-of>` expressions
54+
that return element NodeSets now correctly compute string values using the document
55+
context instead of returning empty strings
56+
57+
### Improved
58+
59+
- Unit tests expanded from 988 to 1010
60+
- Fuzz targets expanded from 10 to 11
61+
862
## [0.3.3] - 2026-03-13
963

1064
### Added
@@ -196,6 +250,8 @@ Initial release of xmloxide — a pure Rust reimplementation of libxml2.
196250
- 119/119 libxml2 compatibility tests (100%)
197251
- Real-world XML, security/DoS, and entity resolver integration tests
198252

253+
[0.4.0]: https://github.com/jonwiggins/xmloxide/releases/tag/v0.4.0
254+
[0.3.3]: https://github.com/jonwiggins/xmloxide/releases/tag/v0.3.3
199255
[0.3.1]: https://github.com/jonwiggins/xmloxide/releases/tag/v0.3.1
200256
[0.3.0]: https://github.com/jonwiggins/xmloxide/releases/tag/v0.3.0
201257
[0.2.0]: https://github.com/jonwiggins/xmloxide/releases/tag/v0.2.0

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**xmloxide** is a pure Rust reimplementation of libxml2 — the de facto standard XML/HTML parsing library in the open-source world. libxml2 became officially unmaintained in December 2025 with known security issues. xmloxide is a memory-safe, high-performance replacement that passes the same conformance test suites.
66

7-
**Version:** 0.3.4
7+
**Version:** 0.4.0
88
**License:** MIT
99
**MSRV:** Rust 1.81+
1010

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "xmloxide"
3-
version = "0.3.4"
3+
version = "0.4.0"
44
edition = "2021"
55
rust-version = "1.81"
66
license = "MIT"

0 commit comments

Comments
 (0)