Lather.Xml.Builder (lather v1.1.0)

Copy Markdown View Source

XML builder for creating SOAP envelopes.

Data structures (maps / keyword-style tuples with @attr, #text, and #content conventions) are converted to XmlBuilder AST tuples and rendered with XmlBuilder.generate/1. No manual string concatenation is used for element construction, and text / attribute escaping is handled by XmlBuilder at render time.

Data shapes

  • %{"tag" => "text"} – element with text content
  • %{"tag" => %{"@attr" => "v", "child" => "x"}} – attributes are @-prefixed keys; every other key is a child element
  • %{"tag" => %{"@attr" => "v", "#text" => "text"}} – attributes plus text content
  • %{"tag" => ["a", "b"]} – a bare list is repeated sibling elements: <tag>a</tag><tag>b</tag>. Each item may itself be a map (with attributes / children). This mirrors Lather.Xml.Parser, which collects repeated elements into a list under one key, so a parsed document rebuilds losslessly.
  • %{"tag" => %{"@attr" => "v", "item" => ["a", "b"]}} – attributes together with repeated children: <tag attr="v"><item>a</item><item>b</item></tag>
  • %{"tag" => %{"@attr" => "v", "#content" => [{"a", "1"}, {"b", "2"}]}}#content renders an ordered list of {tag, value} pairs (or single-key maps) as children, for when child order matters
  • [{"tag", [{"@attr", "v"}, {"child", "x"}]}] – a list of {key, value} pairs is the ordered (keyword-style) form of a map and is accepted anywhere a map is; an empty list renders an empty element

Escaping contract

XmlBuilder's renderer is entity-aware: well-formed entities (&amp;, &lt;, …) in input pass through and resolve on parse, while bare &, <, >, quotes are escaped. Callers that must preserve literal entity-looking text (e.g. a value containing the characters &amp;) should pre-escape with escape_text/1 — this is what Lather.Soap.Body.serialize_params/1 does, keeping the historical raw-text-in / escaped-XML-out contract exact.

Summary

Functions

Builds XML from the given data structure.

Builds XML from a data structure without XML declaration.

Builds XML string from a map structure.

Escapes XML special characters in text content.

Functions

build(data)

@spec build(map() | [{String.t() | atom(), any()}]) ::
  {:ok, String.t()} | {:error, any()}

Builds XML from the given data structure.

Parameters

  • data - Elixir data structure (map) to convert to XML

Examples

iex> {:ok, xml} = Lather.Xml.Builder.build(%{"soap:Envelope" => %{"soap:Body" => %{"operation" => %{}}}})
iex> String.contains?(xml, "<soap:Envelope>")
true
iex> String.contains?(xml, "<operation/>")
true

build_fragment(data)

@spec build_fragment(map() | [{String.t() | atom(), any()}]) ::
  {:ok, String.t()} | {:error, any()}

Builds XML from a data structure without XML declaration.

Useful for building fragments that will be embedded in larger documents.

build_xml_string(data)

@spec build_xml_string(map() | [{String.t() | atom(), any()}]) :: String.t()

Builds XML string from a map structure.

escape_text(text)

@spec escape_text(String.t()) :: String.t()

Escapes XML special characters in text content.

Note: build/1 and build_fragment/1 escape automatically via XmlBuilder, so this helper is only needed when embedding text into XML through other (manual) means.