Beautiful Elixir DSL for building XML documents.

XM turns Elixir syntax into Saxy simple-form XML nodes, then delegates escaping and encoding to Saxy. It is useful for feeds, sitemaps, service integrations, and any code that needs XML without string concatenation.

Supported syntax

  • local calls become XML elements: url do ... end, loc "..."
  • keyword arguments become attributes: link href: "/feed.xml", rel: "self"
  • tag/2 builds dynamic or namespaced names that are awkward as atoms
  • for, if, unless, and case work inside XML blocks
  • text/1, comment/1, and cdata/1 create explicit XML node kinds
  • remote calls, variables, operators, and normal expressions remain Elixir

Examples

import XM

document do
  urlset xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9" do
    url do
      loc "https://example.com/"
      lastmod Date.utc_today()
    end
  end
end

tree do
  tag "media:thumbnail", url: image_url
end

document/2 requires exactly one root element. Use tree/1 when building fragments to embed in a larger document.

Summary

Functions

Build a CDATA node.

Build a comment node.

Build and encode an XML document.

Build an XML element node.

Normalize nested XML nodes and scalar content.

Encode XML nodes through Saxy and return a binary.

Encode XML nodes through Saxy and return iodata.

Build a text node.

Build XML nodes without encoding them.

Types

attribute()

@type attribute() :: {String.t(), String.t()}

prolog()

@type prolog() :: Saxy.Prolog.t() | keyword() | nil

xml_node()

Functions

cdata(value)

@spec cdata(term()) :: Saxy.XML.cdata()

Build a CDATA node.

comment(value)

@spec comment(term()) :: Saxy.XML.comment()

Build a comment node.

document(opts \\ [], list)

(macro)

Build and encode an XML document.

element(name, attrs \\ [], children \\ [])

@spec element(atom() | String.t(), keyword() | map(), term()) :: Saxy.XML.element()

Build an XML element node.

nodes(value)

@spec nodes(term()) :: [term()]

Normalize nested XML nodes and scalar content.

render(nodes, prolog \\ [version: "1.0", encoding: "UTF-8"])

@spec render(xml_node() | [xml_node()], prolog()) :: String.t()

Encode XML nodes through Saxy and return a binary.

render_iodata(nodes, prolog \\ [version: "1.0", encoding: "UTF-8"])

@spec render_iodata(xml_node() | [xml_node()], prolog()) :: iodata()

Encode XML nodes through Saxy and return iodata.

text(value)

@spec text(term()) :: Saxy.XML.characters()

Build a text node.

tree(list)

(macro)

Build XML nodes without encoding them.