Apache Xalan
... is an open-source software library from the Apache Software Foundation that implements the XSLT 1.0 and XPath 1.0 standards. It is primarily used to transform XML documents into HTML, plain text, or other XML types.
Here I'm releasing a free Swift package: XalanSwift that comes with a prebuilt static lib of Xalan-C++ in an XCFramework with a Swift wrapper around it, for Apple Silicon (macOS/iOS). Instructions are included if you may wish to build your own x64 static libs.
Use cases:
XSLT — transform XML with stylesheets
- Transform an in-memory XML string → string (
transform(xml:stylesheet:)) - Transform raw
Data→Data(any encoding the XML prolog declares) - Transform file → file on disk (
transformFile(xml:stylesheet:output:)) - Transform file → string (read from disk, get result in memory)
- Transform using the document's own
<?xml-stylesheet?>PI (no separate stylesheet arg) - Render to HTML, XML, or plain text output (driven by
xsl:output method=)
Reuse for performance (batch / repeated work)
- Compile a stylesheet once, apply it to many documents (
compileStylesheet) - Parse a document once, run many stylesheets against it (
parse) - Mix-and-match compiled stylesheets × parsed sources for N×M transforms cheaply
Pass data into stylesheets
- Set top-level
xsl:paramvalues as: literal strings (any quotes handled), numbers, or raw XPath expressions - Clear/reset parameters between runs
Control the output
- Toggle DTD/schema validation of the source
- Set indentation amount (pretty-print)
- Override the output encoding (UTF-8, ISO-8859-1, …)
XPath — query XML without transforming
- Parse a document from a string or file into a reusable query tree
- Evaluate any XPath 1.0 expression and get a typed result: node-set, number, string, or boolean
- Coerce any result to
.string/.number/.boolean(XPath 1.0 rules) - Enumerate matched nodes (each with name + string value)
- Evaluate relative to a context node (
context:selects where the expression runs) - Convenience one-liners:
string(_:),number(_:),boolean(_:),nodes(_:)
XPath/XSLT power features (verified in the stress tests)
- Namespaces — prefixed lookups, default-namespace handling, namespace shadowing (
namespace-uri(),local-name()) - Aggregation —
count(),sum(), with correct NaN/empty handling - Sorting —
xsl:sortnumeric vs. lexical - Grouping — Muenchian grouping via
xsl:key/generate-id() - Recursion & deep traversal, attribute selection, predicates, self-referential data
- Unicode round-trips (Greek/CJK/emoji), CDATA, escaped entities, mixed content
Things you'd realistically build with it
- Render XML data → HTML pages / reports / emails
- Format conversion: legacy XML → JSON-ish text, CSV, Markdown, other XML schemas
- Data extraction / scraping values out of XML feeds, configs, SOAP/RSS/Atom, SVG, Office Open XML parts
- Validation & assertions ("does this node exist / equal X?") via boolean XPath
- Config/document pipelines where templates are authored separately and fed parameters at runtime
- A CLI or service that batch-transforms many files with a cached compiled stylesheet
Operational properties
- Errors surface as Swift
XalanError(message + code); parse/eval failures are catchable - Auto-initialized, thread-safe global state; one
XSLTProcessorper thread - Self-contained: ships a prebuilt
XalanCore.xcframework(static Xalan + Xerces) — no Homebrew, no system dylibs, no external paths
Current limits (by design)
- XSLT 1.0 / XPath 1.0 only (Xalan doesn't do 2.0/3.0)
- No remote
http(s)fetching indocument()/includes (Xerces built network-off) — local files + in-memory work fully
