An Elixir library for building XML. It is inspired by the late Jim Weirich's awesome builder library for Ruby.
Each XML node is structured as a tuple of name, attributes map, and content/list.
{name, attrs, content | list}
Add dependency to your project's mix.exs
:
def deps do
[{:xml_builder, "~> 2.1"}]
end
Like <person id="12345">Josh</person>
, would look like:
{:person, %{id: 12345}, "Josh"} |> XmlBuilder.generate
Like <person id="12345"><first>Josh</first><last>Nussbaum</last></person>
.
{:person, %{id: 12345}, [{:first, nil, "Josh"}, {:last, nil, "Nussbaum"}]} |> XmlBuilder.generate
For more readability, you can use XmlBuilder's methods instead of creating tuples manually.
XmlBuilder.document(:person, "Josh") |> XmlBuilder.generate
Outputs:
<?xml version="1.0" encoding="UTF-8" ?>
<person>Josh</person>
An element can be built using multiple calls to the element
function.
import XmlBuilder
def person(id, first, last) do
element(:person, %{id: id}, [
element(:first, first),
element(:last, last)
])
end
iex> [person(123, "Steve", "Jobs"),
person(456, "Steve", "Wozniak")] |> generate
Outputs.
<person id="123">
<first>Steve</first>
<last>Jobs</last>
</person>
<person id="456">
<first>Steve</first>
<last>Wozniak</last>
</person>
The previous example can be simplified using a keyed list.
import XmlBuilder
def person(id, first, last) do
element(:person, %{id: id}, first: first,
last: last)
end
iex> person(123, "Josh", "Nussbaum") |> generate(format: :none)
"<person id=\"123\"><first>Josh</first><last>Nussbaum</last></person>"
A DOCTYPE can be declared by applying the doctype
function at the first position of a list of elements in a document
definition:
import XmlBuilder
document([
doctype("html", public: ["-//W3C//DTD XHTML 1.0 Transitional//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"]),
element(:html, "Hello, world!")
]) |> generate
Outputs.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>Hello, world!</html>
While the output is always UTF-8 and has to be converted in another place, you can override the encoding statement in the XML declaration with the encoding
option.
import XmlBuilder
document(:oldschool)
|> generate(encoding: "ISO-8859-1")
|> :unicode.characters_to_binary(:unicode, :latin1)
Outputs.
<?xml version="1.0" encoding="ISO-8859-1"?>
<oldschool/>
Should you need standalone="yes"
in the XML declaration, you can pass standalone: true
as option to the generate/2
call.
import XmlBuilder
document(:outsider)
|> generate(standalone: true)
Outputs.
<?xml version="1.0" standalone="yes"?>
<outsider/>
To remove indentation, pass format: :none
option to XmlBuilder.generate/2
.
doc |> XmlBuilder.generate(format: :none)
The default is to formatting with indentation, which is equivalent to XmlBuilder.generate(doc, format: :indent)
.
This source code is licensed under the MIT License. Copyright (c) 2014-present, Joshua Nussbaum. All rights reserved.