Skip to content

xmojo 0.1.0

Choose a tag to compare

@amarbarosys amarbarosys released this 12 Oct 06:07
· 26 commits to main since this release

xmojo v0.1.0

Released: 2026-10-12 · Previous: first release in this repository

What it does

XML for Mojo: parse into your own structs (from_xml[T]), write them back (to_xml), stream big
documents record by record (Records), or walk a compact tree (parse -> Doc). Built on
emberserde, so a struct that decodes from JSON decodes from XML too. Every gate run checks the
parser against CPython's expat on 4,030 generated, mutated and real documents. Library only,
Mojo 1.1.0, linux-64; pixi install and -I src, or the conda package from recipe.yaml.

Highlights

  • Structs in and out: attributes, child elements, text, Optional, List, Dict and unit enums,
    with from_xml[T](to_xml(v, "r")) giving v back.
  • Conforming: XML 1.0 well-formedness and Namespaces in XML, including attribute namespaces,
    xml:space, line-end and attribute normalization; 0 disagreements with expat.
  • Fast and small: 1.1 MB parsed in 15.4 ms (CPython's C ElementTree: 29.9 ms), about 100 bytes
    per element; Records keeps one record's tree in memory instead of the document's.
  • emberserde's modifiers work (Rename, RenameAll, Skip, Defaulted, aliases,
    DenyUnknownFields), and an agent skill ships in skills/xmojo/ (Claude Code plugin
    marketplace layout, AGENTS.md for other agents).

Changes

First release in this repository. Public API:

  • from_xml[T](text, entities=...), to_xml(value, root).
  • Records(text, local).next() -> Optional[String].
  • parse(text, entities=...) -> Doc and the Doc accessors listed in README, "DOM".
  • html_entities() for opt-in HTML named references; XmlError for malformed input.
  • Mapping rules, XML handling and limits: README. Agent skill: skills/xmojo/SKILL.md.

Verified

Check Result
pixi run gate: 9 unit-test files (incl. the README example as assertions), tool builds, tools/oracle.py seeds 1 and 7 (2015 documents each) against expat, --negative control, every runnable Mojo snippet in README and the skill PASS: 35/35 tests, 2015/2015 on both seeds, negative control 53/215 differ, snippets 3/3
pixi run package (rattler-build 0.76.1): build, then every tests/test_*.mojo importing the installed xmojo.mojoc xmojo-0.1.0-hb0f4dca_0.conda, 9/9 files, 35/35 tests; LICENSE and NOTICE in the package
2 GiB guard, once by hand (6.3 GB, 4 s, so not in the gate) parse raises on a 2,147,483,663-byte input; Records walks it
Fresh clone of the published tree: pixi install in an empty directory, then pixi run gate and pixi run build PASS, clone tree identical to the published one

Known limits

  • No DTDs: an internal subset is skipped, so its entities are unknown and raise.
  • UTF-8 only: a declared encoding other than UTF-8 or US-ASCII raises.
  • parse and from_xml take up to 2 GiB per document (Int32 offsets); Records can walk larger
    inputs, each record up to 2 GiB, but the input must be in memory.
  • Records copies and parses each record on its own: 3.5 times slower than whole-document
    from_xml on 14-byte records.
  • to_xml: no namespaces, no pretty-printing; enum arms with payloads and tuples are unsupported
    in both directions.

Upgrade / run

pixi install
pixi run gate

Commits

  • xmojo 0.1.0: initial public commit.