Libraries
FnXML
activeA pure-Elixir streaming XML library that parses documents into lazy streams of events.
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
- Events are the basic format. Every XML construct becomes an event tuple carrying its location. Because the parser produces an ordinary Elixir stream, you can stop early once you find what you need, and a slow consumer naturally slows the parser.
- Constant memory. The core parser and the built-in transforms hold O(1) memory, so multi-gigabyte files can be processed incrementally. Operations you add downstream, such as grouping, may buffer.
- Use only what you need. Each stage is optional: skip validation for trusted input, or skip namespace resolution when there are none.
- Generated parsers.
use FnXML.Parser.Generatorbuilds a specialised parser at compile time that drops event kinds you don't want (whitespace, comments, CDATA, even text) and can turn off position tracking entirely. - Both XML 1.0 editions. Edition 5 (permissive, the default) and Edition 4 (strict character validation) are both supported.
- A shared event contract. Events follow a versioned contract shared by every producer and consumer in the Fn* family. Each stream is bracketed by start and end document events whose properties state how names and text are represented.
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.