Portable C17
One code base. It depends on nothing outside the repository and builds with Clang, GCC and Zig.
sxml parses XML and HTML, validates documents against XSD 1.1 schemas and DTDs, and runs XPath 4.0, XQuery 4.0 and XSLT 4.0. It is a C library with no dependencies, the sxml command, and a WebAssembly module for JavaScript.
Three lines of text become XML, are validated, queried, rebuilt and rendered as HTML. The files and outputs below are real, recorded with the sxml command.
An Invisible XML grammar describes the order's text format. fn:invisible-xml compiles the grammar into a function, and the function turns the text into XML.
2 x tea @ 3.50
1 x coffee @ 4.20
3 x scone @ 2.10order: line+.
line: quantity, -" x ", item, -" @ ", price, -#a.
quantity: digit+.
item: ["a"-"z"]+.
price: digit+, ".", digit, digit.
-digit: ["0"-"9"].sxml xpath --method=xml \
'invisible-xml(unparsed-text("order.ixml"))(unparsed-text("order.txt"))' \
-o order.xmlsxml serialize --indent order.xml<order>
<line>
<quantity>2</quantity>
<item>tea</item>
<price>3.50</price>
</line>
<line>
<quantity>1</quantity>
<item>coffee</item>
<price>4.20</price>
</line>
<line>
<quantity>3</quantity>
<item>scone</item>
<price>2.10</price>
</line>
</order>All languages share one data model, XDM 4.0, and every build includes every feature.
One code base. It depends on nothing outside the repository and builds with Clang, GCC and Zig.
The library never calls malloc. Every object takes an sxml_allocator, or goes in memory you provide after a memory_requirements query.
The parsers and the evaluator use explicit stacks. Deeply nested input does not overflow the C stack; depth and work have limits you configure.
XPath, XQuery and XSLT compile to one intermediate representation, run on one evaluator and share one data model, XDM 4.0.
Separate processors share nothing, so a program can run as many as it needs, on as many threads.
sxml reads only what your resource resolver gives it. File access through EXPath File is off until a host turns it on.
In an XSLT mode declared streamable="yes", sxml transform reads its input as it parses it and does not build a tree. Summing one million orders in a 76 MB document takes 11 MB of memory; a 974 MB document also takes 11 MB.
sxml transform total.xsl orders.xml on a 76 MB inputResults against the W3C and community test suites, from a release build at commit e74d4ad on 2026-10-20.
| Suite | Run | Passed | Rate |
|---|---|---|---|
| XPath 4.0 and F&O 4.0QT4 · XP40 | 32,841 | 32,815 | 99.92 % |
| XQuery 4.0, Update and Full TextQT4 · XQ40 | 46,232 | 46,158 | 99.84 % |
| XSLT 4.0XT40 | 12,518 | 12,268 | 98.00 % |
| XSD 1.1W3C XSD test suite | 41,610 | 41,599 | 99.97 % |
| XML 1.0 and 1.1W3C XML Conformance Test Suite | 2,237 | 2,237 | 100.00 % |
| HTML tokenizerhtml5lib | 7,045 | 7,045 | 100.00 % |
| Invisible XMLCommunity test suite | 886 | 886 | 100.00 % |
Bars start at 95 %. Results by test set
Subcommands check, validate, xpath, xquery, transform and serialize. Static executables for x86_64 and AArch64, and a WebAssembly program for WASI runtimes.
sxml helpA processor holds names, types and values. Expressions, queries, stylesheets and schemas compile once and run against any number of documents.
#include "sxml/xpath.h"The @tinyactors/sxml package: the same library compiled to WebAssembly, with a TypeScript API and no runtime dependencies.
import { load } from '@tinyactors/sxml'A guide to sxml and its languages: installing it, XPath, XQuery, XSLT, XSD, other formats, and embedding sxml in C and JavaScript. Each part is taught on a project for one made-up feature-flag service, from its specification to its generated SDK clients.