Current section

Files

Jump to
elixir_xml_to_map lib xml_to_map naive_map.ex
Raw

lib/xml_to_map/naive_map.ex

defmodule XmlToMap.NaiveMap do
@moduledoc """
Module to recursively traverse the output of erlsom.simple_form
and produce a map.
erlsom uses character lists so this library converts them to
Elixir binary string.
Attributes, if present, are defined as tag@attribute_name => attribute_value
"""
def parse([value]) do
case is_tuple(value) do
true -> parse(value)
false -> to_string(value) |> String.trim
end
end
def parse({name, attr, content}) do
attributes = Enum.reduce(attr, %{}, fn({attribute_name, attribute_value}, acc) ->
Map.put(acc, "#{name}@#{attribute_name}", to_string(attribute_value))
end)
parsed_content = parse(content)
case is_map(parsed_content) do
true ->
%{to_string(name) => parsed_content |> Map.merge(attr_map(attr)) |> Map.merge(attributes)}
false ->
%{to_string(name) => parsed_content} |> Map.merge(attributes)
end
end
def parse(list) when is_list(list) do
parsed_list = Enum.map list, &({to_string(elem(&1, 0)), parse(&1)})
Enum.reduce parsed_list, %{}, fn {k,v}, acc ->
case Map.get(acc, k) do
nil ->
(for {key, value} <- v, into: %{}, do: {key, value})
|> Map.merge(acc)
[h|t] -> Map.put(acc, k, [h|t] ++ [v[k]])
prev -> Map.put(acc, k, [prev] ++ [v[k]])
end
end
end
defp attr_map(list) do
list |> Enum.map(fn {k,v} -> {to_string(k), to_string(v)} end) |> Map.new
end
end