COOLJAPAN
← All posts

OxiXML 0.1.1 Released — A Typed SVG Model, Unbounded Precision, and a Global-Variable Fix 156× Faster

OxiXML 0.1.1 is a hardening release: a new typed SVG 1.1/2.0 document model, arbitrary-precision xs:integer/xs:decimal by default, and the query/transform tier locked to its W3C suites — XPath and XQuery 100%, XSLT 98.9%, XSD 1.0/1.1 99.9%. Deliberately breaking, no compatibility shims: 0.1.0 is superseded. Pure Rust, 0 external crates in default features.

release oxixml xml svg xslt xpath rdf pure-rust

Six-point-three seconds became forty milliseconds, and a graphics format with no Pure-Rust home before now has one.

Today we released OxiXML 0.1.1 — a hardening release that finishes the query/transform tier against its W3C suites, adds a typed SVG document model, and makes arbitrary-precision xs:integer/xs:decimal the workspace default.

No C, no C++, no Fortran — still the same zero-external-crates-by-default Pure-Rust workspace introduced at 0.1.0. 0.1.1 breaks compatibility with 0.1.0 deliberately and ships no compatibility shims: 0.1.0 is superseded and is being yanked from crates.io, so 0.1.1 is the version to depend on. It compiles to a single static binary, targets WASM, and runs everywhere.

Why OxiXML 0.1.1 is a game changer

At 0.1.0, four things were true that don’t hold anymore:

0.1.1 ends all of that:

Technical Deep Dive: four fronts

  1. SVG, built on the existing tree. oxixml-svg adds no new tree type — SvgDocument/SvgElement sit over oxixml-dom, so the same namespace-aware, serialization-safe core that parses arbitrary XML also parses SVG. A geometry engine computes bounding boxes, arc length, and point-at-length per SVG Appendix F math; a CSS cascade covers a documented selector subset; the linter carries 18 diagnostic codes.
  2. Numbers without a ceiling. New BigInteger/BigDecimal atomics in oxixml-infoset thread through casts, large to ranges, and map-key / distinct-values / index-of / sort semantics — fixed-width in-range values stay byte-identical, so this is pure added capability, not a performance regression.
  3. Correctness the conformance suites forced. A cooperative deadline (EvaluationLimits::declare_deadline, Parameters::with_deadline) stops a runaway expression or stylesheet with the spec’s own XPDY0130 code, checked between evaluation steps rather than on a hard-kill timer. fn:transform lets a stylesheet invoke another XSLT processor. xsl:apply-imports/xsl:next-match now search the correct import-precedence window, so an overridden rule can’t re-match itself.
  4. Security hardening in oxixml-dsig/oxixml-enc. DSA and ECDSA (P-256/P-384) sign+verify with RFC 6979 deterministic nonces, RSASSA-PSS sign+verify, RFC 5280 X.509 certification-path validation via a public PathValidator, and ECDH-ES/DH-ES key agreement via ConcatKDF — alongside the RSA exponent cap above.

Getting Started

Add the new SVG crate:

cargo add oxixml-svg
use oxixml_svg::{Length, LengthUnit, Linter, Rect, SvgBuilder, SvgDocument};

fn main() {
    // Parse a document and read a typed presentation attribute.
    let doc = SvgDocument::parse_str(
        r#"<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
             <rect x="10" y="20" width="50" height="30"/>
           </svg>"#,
    )
    .expect("well-formed SVG");
    assert_eq!(doc.width(), Some(Ok(Length::new(200.0, LengthUnit::None))));

    // Compute the rect's bounding box through the geometry engine: turn it
    // into its equivalent path, then measure that path.
    let rect = doc.svg_element().children().next().expect("the rect element");
    let ctx = oxixml_svg::values::length::LengthContext::default();
    let path = oxixml_svg::tree::shapes::equivalent_path(rect, &ctx)
        .expect("rect is a recognized shape")
        .expect("its geometry attributes are all valid");
    let bbox =
        oxixml_svg::geometry::path_ops::bounding_box(&path).expect("a non-empty rect has a bbox");
    assert_eq!(bbox, Rect::new(10.0, 20.0, 50.0, 30.0).expect("a valid rect"));

    // Lint the document: nothing here is unknown, deprecated, or dangling.
    let diagnostics = Linter::new().lint(doc.document());
    assert!(diagnostics.is_empty());
}

Or pull it in through the facade instead of the standalone crate:

[dependencies]
oxixml = { version = "0.1.1", features = ["svg"] }

What’s New in 0.1.1

Breaking

Added

Fixed

Full itemized detail is in the CHANGELOG.

Tips

This is the foundation

OxiXML depends on nothing else in the ecosystem, so any project can adopt it without a dependency cycle. OxiRS, OxiGeo, OxiMedia, Legalis-RS, and every COOLJAPAN project migrating off quick-xml or an Oxigraph crate sit on top of it tier by tier — and now so does anything that needs to emit or read SVG without hand-rolling its own escaping.

Repository: https://github.com/cool-japan/oxixml

Star the repo if you want SVG, unbounded-precision numbers, and a query/transform tier held to a byte-identical, four-run conformance ledger — in Rust, with no JVM or C library underneath.

The era of hand-rolled SVG strings and silently-recopied global variables is over. Pure Rust XML and RDF — complete, conformant, and sovereign — is here.

KitaSan at COOLJAPAN OÜ August 6, 2026

↑ Back to all posts