What it is

FnXML is a pure-Elixir XML library that parses XML into lazy streams of events. Those events flow through a pipeline of optional components (preprocessing, validation, DTD and namespace resolution, filters) and end in whatever consumer you choose: plain Stream and Enum functions, or the familiar DOM, SAX and StAX APIs built on top of the stream.

It is the foundation of a small family of document libraries. FnHTML parses HTML5 into the same event stream, FnCSS styles the resulting documents, and FnLayout lays them out for rendering to PDF, PNG or SVG.

Example

The full, standards-compliant pipeline, or only the parts you need:

File.stream!("data.xml")
|> FnXML.preprocess()                      # Preprocess: UTF-16 + line endings
|> FnXML.Parser.parse()                    # Parse XML to event stream
|> FnXML.Event.Validate.compliant()        # Full XML 1.0 validation
|> FnXML.Event.resolve()                   # Resolve DTD + namespaces
|> FnXML.API.SAX.dispatch(Handler, state)

FnXML.process/1 applies that whole pipeline in one call, and the result can be collected into a tree with FnXML.API.DOM.build/1.

Design notes

Standards

FnXML implements XML 1.0 (Fourth and Fifth Editions, including DTDs), Namespaces in XML 1.0, Canonical XML 1.0 and Exclusive XML Canonicalization 1.0. A conformance runner exercises both editions against the W3C/OASIS XML Conformance Test Suite, about 2,000 tests.

XML Signature and XML Encryption support (RSA-SHA2 signatures, AES-GCM and AES-CBC encryption, RSA-OAEP key transport, all on OTP's :crypto and :public_key) is in development. It has not had a security review and should not be used for security-critical work.

Status

FnXML is at version 0.3 and under active development. It is not yet published to Hex: it depends on the shared event-contract package, which has to be published first. The XML parsing, validation and API layers are the mature part of the library; the security modules are not. MIT licensed.