Cfdi.Decoder (cfdi v4.0.6)

Copy Markdown

Decodifica un XML CFDI 4.0 a un %Cfdi.Comprobante{} completo.

Es el camino inverso de CFDI.to_xml/2. La API pública vive en CFDI.from_xml/2 y CFDI.from_file/2; este módulo es el motor.

Por qué no reusa Cfdi.Xml.Parser

Cfdi.Xml.Parser produce un mapa de lectura: aplana todo a llaves del mismo tipo y adivina la pluralización por heurística de nombres. Eso sirve para inspeccionar un CFDI, no para reconstruirlo.

La serialización (CFDI.to_xml/2) se apoya en una convención estricta:

  • llave átomo (:Version) → atributo XML
  • llave string ("cfdi:Emisor") → elemento hijo

Este decoder respeta esa convención y toma la forma de cada elemento del DSL (Cfdi.Xml.Element.__xml__/1), que es la fuente de verdad de qué es atributo y qué es hijo. Por eso from_xml |> to_xml roundtrippea.

Namespaces

La resolución de complementos va por la URI del namespace, con herencia de scope: un xmlns:foo declarado en la raíz aplica a los descendientes. Un CFDI puede declarar el namespace del complemento en la raíz (vehiculo_usado.xml) o en el propio elemento (cfdi-completo.xml); ambos casos se resuelven igual. El prefijo es irrelevante — ver Cfdi.Complementos.Complemento.

Summary

Functions

Decodifica un XML CFDI a %Cfdi.Comprobante{}.

Types

reason()

@type reason() :: {:malformed_xml, term()} | {:unexpected_root, String.t()}

Functions

decode(xml)

@spec decode(String.t()) :: {:ok, Cfdi.Comprobante.t()} | {:error, reason()}

Decodifica un XML CFDI a %Cfdi.Comprobante{}.