Facturx.XSD (Facturx v0.2.0)

Copy Markdown View Source

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_xsd is 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 in Facturx.Validate (Schematron).

Summary

Types

An XSD validation error — the raw :xmerl_xsd reason, inspected.

Functions

Validate xml against the profile's CII XSD.

Types

error()

@type error() :: String.t()

An XSD validation error — the raw :xmerl_xsd reason, inspected.

Functions

validate(xml, opts \\ [])

@spec validate(
  binary(),
  keyword()
) :: {:ok, :valid} | {:error, {:invalid, [error()]}} | {:error, term()}

Validate xml against the profile's CII XSD.

Options:

  • :profile — schema to use (default: detected from the XML, else :en16931)