Validate CII XML against the official EN 16931 XSD — pure Elixir, in-process.
Uses OTP's :xmerl_xsd (no external tool, no network, no Port).
When the :facturx application is running, Facturx.XSD.Cache compiles each
bundled schema once and shares it via :persistent_term, so validation runs in
the caller process — in parallel, ~0.6 ms/call. If the cache isn't running
(or a cached schema's table has gone away), it falls back to compiling per call
(~5 ms) inside a short-lived task, so the schema's ETS table is reclaimed on
exit.
Only the :en16931 profile schema ships today (priv/xsd/en16931/); other
profiles return {:error, {:xsd_not_bundled, profile}}.
Security
Input is treated as untrusted. A <!DOCTYPE> is rejected and external
entity/DTD fetching is disabled, so neither XXE (external entity file/URL
reads) nor entity-expansion bombs ("billion laughs") are possible. Legitimate
CII/Factur-X XML never carries a DTD.
:xmerl_xsdis a partial XSD 1.0 implementation. On the CII EN 16931 schema it correctly catches missing mandatory elements, wrong data types, unexpected elements, wrong order and cardinality — but it is not a guarantee of full XSD 1.0 conformance. Business rules live inFacturx.Validate(Schematron).
Summary
Functions
Validate xml against the profile's CII XSD.
Types
@type error() :: String.t()
An XSD validation error — the raw :xmerl_xsd reason, inspected.