Skip to content

Commit fb67a25

Browse files
committed
release: prepare 0.4.1 with FFI parity, binding improvements, docs sync
Add Schematron and CSS selector support to C FFI, bringing it to parity with Rust/Python/WASM. Add tree mutation APIs to WASM binding. Add CSS selectors to Python binding. Expand benchmarks with validation, XPath, and CSS suites. Add 58 CSS evaluator tests and 10 FFI tests. Fix README which incorrectly listed Schematron as unsupported and XPath as 1.0 only. Update MIGRATION.md with HTML5, Schematron, and CSS migration examples.
1 parent d8e36ef commit fb67a25

18 files changed

Lines changed: 1840 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,49 @@ 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.1] - 2026-03-15
9+
10+
### Added
11+
12+
- **Schematron C FFI**`xmloxide_parse_schematron`, `xmloxide_free_schematron`,
13+
`xmloxide_validate_schematron`, and `xmloxide_validate_schematron_with_phase` for
14+
C/C++ consumers; Schematron was previously only available in Rust, Python, and WASM
15+
- **CSS selector C FFI**`xmloxide_css_select`, `xmloxide_css_select_first`, and
16+
`xmloxide_free_nodeid_array` for querying elements with CSS selectors from C/C++
17+
- **CSS selectors in Python**`css_select()` and `css_select_first()` methods on
18+
`Document` in pyxmloxide
19+
- **WASM tree mutation APIs**`createElement`, `createText`, `createComment`,
20+
`appendChild`, `removeNode`, `setAttribute`, `removeAttribute`, `setTextContent`,
21+
`insertBefore`, `cloneNode` on `WasmDocument`
22+
- **Validation benchmarks** — criterion benchmarks for DTD, RelaxNG, XSD, and
23+
Schematron validation
24+
- **Expanded XPath benchmarks** — count, string function, position predicate,
25+
ancestor axis, and union expression benchmarks
26+
- **CSS selector benchmarks** — class selector and complex combinator benchmarks
27+
- 58 CSS evaluator inline tests covering tag, class, ID, attribute, pseudo-class,
28+
combinator, and universal selector matching
29+
- 10 new FFI tests (5 Schematron + 5 CSS) bringing FFI test total to 138
30+
31+
### Fixed
32+
33+
- **README incorrectly listed Schematron as unsupported** — the Limitations section
34+
claimed "No Schematron" despite Schematron being added in 0.4.0
35+
- **README listed XPath as "1.0 only"** — updated to "XPath 1.0+" reflecting the
36+
17+ XPath 2.0 functions added in prior releases
37+
- **Outdated test counts in README** — updated from 936 to 1078 unit tests
38+
39+
### Improved
40+
41+
- Unit tests expanded from 1010 to 1078
42+
- FFI tests expanded from 128 to 138
43+
- README now documents serde, async, and Schematron features
44+
- MIGRATION.md expanded with HTML5 parsing, HTML5 streaming, Schematron validation,
45+
and CSS selector migration examples
46+
- CLAUDE.md module map updated with css/, serde_xml/, async_xml, and full ffi/ listing
47+
- `xmllint --schematron` added to CLI documentation in README
48+
- Schematron added to migration table in README
49+
- `xmloxide.h` header updated with Schematron and CSS selector declarations
50+
851
## [0.4.0] - 2026-03-14
952

1053
### Added

CLAUDE.md

Lines changed: 35 additions & 6 deletions
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.4.0
7+
**Version:** 0.4.1
88
**License:** MIT
99
**MSRV:** Rust 1.81+
1010

@@ -13,11 +13,15 @@
1313
- Full conformance with W3C XML 1.0 (Fifth Edition) and Namespaces in XML 1.0
1414
- **1727/1727** W3C XML Conformance Test Suite tests passing (100%)
1515
- **119/119** libxml2 regression tests passing (100%)
16-
- Feature parity with libxml2's core: XML/HTML parsing, DOM, SAX2, XPath 1.0, XmlReader, push parser, DTD/RelaxNG/XSD/Schematron validation, C14N, XInclude, XML Catalogs
16+
- Feature parity with libxml2's core: XML/HTML parsing, DOM, SAX2, XPath 1.0+, XmlReader, push parser, DTD/RelaxNG/XSD/Schematron validation, C14N, XInclude, XML Catalogs
1717
- **WHATWG HTML5 parser** — full HTML Living Standard tokenizer (§13.2.5) and tree builder (§13.2.6) with 7032/7032 tokenizer tests + 1778/1778 tree construction tests passing (100% html5lib-tests)
18+
- **CSS selector engine** — query elements with familiar CSS syntax including combinators and pseudo-classes
19+
- **Serde integration** — optional XML (de)serialization to/from Rust types via serde
20+
- **Async parsing** — optional async parsing from `tokio::io::AsyncRead` sources
1821
- Zero `unsafe` in public API surface (`unsafe_code = "deny"` in Cargo.toml)
1922
- No system dependencies — pure Rust (uses `encoding_rs` for character encoding)
2023
- C/C++ FFI layer with header file (`include/xmloxide.h`)
24+
- WASM bindings (`xmloxide-wasm`) and Python bindings (`pyxmloxide`)
2125
- `xmllint` CLI tool
2226
- Performance competitive with libxml2 (serialization 1.5-2.3x faster)
2327

@@ -67,7 +71,13 @@ src/
6771
│ ├── mod.rs # WHATWG HTML5 parser public API and module docs
6872
│ ├── tokenizer.rs # HTML5 tokenizer (all 80 states per §13.2.5)
6973
│ ├── tree_builder.rs # HTML5 tree construction (all insertion modes per §13.2.6)
74+
│ ├── sax.rs # HTML5 SAX-like streaming API (no DOM tree)
7075
│ └── entities.rs # HTML5 named character references (§13.5, 2231 entries)
76+
├── css/
77+
│ ├── mod.rs # CSS selector public API (select, select_with)
78+
│ ├── parser.rs # CSS selector parser
79+
│ ├── types.rs # Selector AST types
80+
│ └── eval.rs # Selector evaluator against document trees
7181
├── sax/
7282
│ └── mod.rs # SAX2 handler trait and streaming parser
7383
├── reader/
@@ -80,7 +90,8 @@ src/
8090
│ ├── lexer.rs # XPath expression tokenizer
8191
│ ├── parser.rs # XPath expression parser → AST
8292
│ ├── eval.rs # Expression evaluator against a node tree
83-
│ └── types.rs # XPath value types (NodeSet, String, Number, Boolean)
93+
│ ├── types.rs # XPath value types (NodeSet, String, Number, Boolean)
94+
│ └── regex.rs # XPath regex support (matches, replace, tokenize)
8495
├── validation/
8596
│ ├── mod.rs # ValidationResult, ValidationError
8697
│ ├── dtd.rs # DTD parsing and validation (populates id_map)
@@ -96,12 +107,27 @@ src/
96107
│ └── mod.rs # XInclude 1.0 document inclusion
97108
├── catalog/
98109
│ └── mod.rs # OASIS XML Catalogs for URI resolution
110+
├── serde_xml/
111+
│ ├── mod.rs # Serde XML module root (feature-gated behind "serde")
112+
│ ├── de.rs # XML deserializer
113+
│ ├── ser.rs # XML serializer
114+
│ └── error.rs # Serde error types
115+
├── async_xml.rs # Async parsing via tokio::io::AsyncRead (feature-gated "async")
99116
├── ffi/
100117
│ ├── mod.rs # FFI module root (feature-gated behind "ffi")
101118
│ ├── document.rs # Document parsing FFI
102119
│ ├── tree.rs # Tree navigation FFI
103120
│ ├── serial.rs # Serialization FFI
104121
│ ├── xpath.rs # XPath evaluation FFI
122+
│ ├── validation.rs # DTD/RelaxNG/XSD/Schematron validation FFI
123+
│ ├── css.rs # CSS selector FFI
124+
│ ├── sax.rs # SAX2 streaming FFI
125+
│ ├── reader.rs # XmlReader FFI
126+
│ ├── push.rs # Push parser FFI
127+
│ ├── c14n.rs # Canonical XML FFI
128+
│ ├── catalog.rs # XML Catalogs FFI
129+
│ ├── html5.rs # HTML5 parsing FFI
130+
│ ├── xinclude.rs # XInclude FFI
105131
│ └── strings.rs # String memory management FFI
106132
├── error/
107133
│ └── mod.rs # Error types, ParseError, ParseDiagnostic
@@ -213,7 +239,8 @@ These are the specs we implement against:
213239

214240
- [XML 1.0 (Fifth Edition)](https://www.w3.org/TR/xml/) — the core spec
215241
- [Namespaces in XML 1.0](https://www.w3.org/TR/xml-names/) — namespace processing
216-
- [XPath 1.0](https://www.w3.org/TR/xpath-10/) — XPath query language
242+
- [XPath 1.0](https://www.w3.org/TR/xpath-10/) — XPath query language (with selected XPath 2.0 functions)
243+
- [ISO Schematron](https://www.iso.org/standard/40833.html) — ISO/IEC 19757-3 rule-based validation
217244
- [XML Inclusions (XInclude) 1.0](https://www.w3.org/TR/xinclude/) — document merging
218245
- [Canonical XML 1.0](https://www.w3.org/TR/xml-c14n/) — canonical serialization
219246
- [RelaxNG](https://relaxng.org/spec-20011203.html) — schema language
@@ -358,7 +385,7 @@ Pre-commit hooks available via `./scripts/install-hooks.sh` (runs fmt, clippy, t
358385

359386
| Suite | Location | Tests | Notes |
360387
|-------|----------|-------|-------|
361-
| Unit tests | `src/**/*.rs` (inline) | 991 | All modules |
388+
| Unit tests | `src/**/*.rs` (inline) | 1020+ | All modules |
362389
| W3C Conformance | `tests/conformance.rs` | 1727/1727 | Requires `download-conformance-suite.sh` |
363390
| libxml2 Compat | `tests/libxml2_compat.rs` | 119/119 | Requires `download-libxml2-tests.sh` |
364391
| html5lib Tokenizer | `tests/html5lib_tokenizer.rs` | 7032/7032 | Requires `download-html5lib-tests.sh` |
@@ -367,6 +394,8 @@ Pre-commit hooks available via `./scripts/install-hooks.sh` (runs fmt, clippy, t
367394
| Real-world XML | `tests/real_world_xml.rs` | 22 | Atom, SVG, XHTML, Maven, SOAP, validation |
368395
| Security/DoS | `tests/security.rs` | 15 | Billion laughs, deep nesting, etc. |
369396
| Entity resolver | `tests/entity_resolver.rs` | 14 | Entity expansion edge cases |
370-
| FFI | `tests/ffi_tests.rs` | 112 | C API surface tests (including SAX) |
397+
| FFI | `tests/ffi_tests.rs` | 138+ | C API surface tests (SAX, Schematron, CSS) |
371398
| Schematron | `tests/schematron.rs` | 11 | PO schema, phases, firing rules, namespaces |
399+
| Property tests | `tests/property_tests.rs` || Proptest roundtrip invariants |
400+
| UBL Validation | `tests/ubl_validation.rs` | 2 | Real-world UBL 2.4 XSD (requires download) |
372401
| Fuzz targets | `fuzz/` | 11 targets | XML, HTML, HTML5, XPath, roundtrip, SAX, reader, push, validation, schematron |

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.4.0"
3+
version = "0.4.1"
44
edition = "2021"
55
rust-version = "1.81"
66
license = "MIT"

0 commit comments

Comments
 (0)