View Source Saxaboom.Mapper (Saxaboom v0.2.1)
The main user interface for defining mapping definitions.
Saxaboom.Mapper
exposes a micro-DSL for describing the expected structure of a given document. There are three
components to the Saxaboom.Mapper
interface:
document/1
: a directive describing the "envelope" of the incoming document (read: the whole document). This exposes the internal DSL.element/2
: a directive to match zero to one element and collect into a single struct fieldelements/2
: a directive to match zero to N elements and collect in a list in the order they are encounteredattribute/2
: a directive to match zero to one attribute and collect into a single struct field.
Please note that the element/2
and attribute/2
macros take a "last argument wins" approach, which is to say that
if an element or attribute of the same name appears later in the document, the value extracted will overwrite any previously
held value.
Examples
For example, the following mapper defines a bookstore catalog of books (see also: examples):
defmodule Book do
use Saxaboom.Mapper
document do
attribute :id
element :author
element :title
element :genre
element :price, cast: :float
element :publish_date, cast: &__MODULE__.parse_date/1
element :description
end
def parse_date(value), do: Date.from_iso8601(value)
end
defmodule Catalog do
use Saxaboom.Mapper
document do
elements :book, as: :books, into: %Book{}
end
end
Which intuitively maps against the following XML body:
xml = """
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
</catalog>
"""
Usage:
Saxaboom.parse(xml, %Catalog{})
#=> {:ok,
# %Catalog{
# books: [
# %Book{
# id: "bk101",
# author: "Gambardella, Matthew",
# title: "XML Developer's Guide",
# genre: "Computer",
# price: 44.95,
# publish_date: {:ok, ~D[2000-10-01]},
# description: "An in-depth look at creating applications\n with XML."
# }
# ]
# }}
use Saxaboom.Mapper
When you
use Saxaboom.Mapper
, the mapper module will import theelement/2
andelements/2
macros into the current scope.
Consolidation
Saxaboom currently relies on dynamic dispatch via protocols, which are consolidated at compile time for a performance boost. If you'd like to use Saxaboom in iex and dynamically create
Saxaboom.Mapper
s, you should read the docs on consolidation for the finer details and config options available. Turning off protocol consolidation is not generally recommended for production environments.
Summary
Functions
Defines a structure field that can match against an attribute in the given document. Note that the element it extracts from is unspecified, it will extract from any element that has the given attribute.
Begins the definition of a "document", that is, a section of parseable content.
Defines a structure field that can match against 0 or 1 elements in the given document.
Defines a structure field that can match against 0 or N elements in the given document. The list will be parsed and extracted in document order. Defaults to an empty list.
Functions
Defines a structure field that can match against an attribute in the given document. Note that the element it extracts from is unspecified, it will extract from any element that has the given attribute.
This macro is helpful to extract multiple attributes from a single node, while the element/2
and elements/2
macros
only allow for the extraction of a single attribute from a node.
Arguments:
name
is the name of the attribute to match against, case sensitive
Options:
:as
provides the name to be used on the struct when parsing, defaults to the name of the tag:cast
is a symbol or a user-defined function to transform the extracted:value
, seeSaxaboom.Utils.Caster
for more details.
Begins the definition of a "document", that is, a section of parseable content.
Defines a structure field that can match against 0 or 1 elements in the given document.
Arguments:
name
is the name of the tag to match against, case sensitive
Options:
:as
provides the name to be used on the struct when parsing, defaults to the name of the tag:value
identifies the property to extract from the tag. Can be an attribute name, defaults to the text content of the node:with
is a keyword list of attributes and expected attribute values. The:with
must perfectly match against a subset of the node attributes:cast
is a symbol or a user-defined function to transform the extracted:value
, seeSaxaboom.Utils.Caster
for more details.:into
is another mapper or type that implements theSaxaboom.ElementCollectable
protocol. Child nodes will be parsed into this structure until the parser has encountered the closing tag of the node that began the:into
.:default
is the default value of the node, if no tags are parsed.nil
by default
Defines a structure field that can match against 0 or N elements in the given document. The list will be parsed and extracted in document order. Defaults to an empty list.
Arguments:
name
is the name of the tag to match against, case sensitive
Options:
:as
provides the name to be used on the struct when parsing, defaults to the name of the tag:value
identifies the property to extract from the tag. Can be an attribute name, defaults to the text content of the node:with
is a keyword list of attributes and expected attribute values. The:with
must perfectly match against a subset of the node attributes:cast
is a symbol or a user-defined function to transform the extracted:value
, seeSaxaboom.Utils.Caster
for more details.:into
is another mapper or type that implements theSaxaboom.ElementCollectable
protocol. Child nodes will be parsed into this structure until the parser has encountered the closing tag of the node that began the:into
.