Current section
Files
Jump to
Current section
Files
lib/xml_parser/xml_parser.ex
defmodule Quinn.XmlParser do
def parse(xml, options \\ %{}) do
:erlang.bitstring_to_list(xml)
|> :xmerl_scan.string
|> elem(0)
|> parse_record(options)
end
defp combine_values([]), do: []
defp combine_values(values) do
if Enum.all?(values, &(is_binary(&1))) do
[List.to_string(values)]
else
values
end
end
defp parse_record({:xmlElement, name, _, _, _, _, _, attributes, elements, _, _, _}, options) do
value = combine_values(parse_record(elements, options))
name = parse_name(name, options)
[%{name: name, attr: parse_attribute(attributes), value: value}]
end
defp parse_record({:xmlText, _, _, _, value, _}, _) do
string_value = String.strip(to_string(value))
if (String.length(string_value) > 0) do
[string_value]
else
[]
end
end
defp parse_record({:xmlComment, _, _, _, value}, options) do
if options[:comments] do
[%{name: :comments, attr: [], value: String.strip(to_string(value))}]
else
[]
end
end
defp parse_record([], _), do: []
defp parse_record([head | tail], options) do
parse_record(head, options) ++ parse_record(tail, options)
end
defp parse_attribute([]), do: []
defp parse_attribute({:xmlAttribute, name, _, _, _, _, _, _, value, _}) do
[{name, to_string(value)}]
end
defp parse_attribute([head | tail]) do
parse_attribute(head) ++ parse_attribute(tail)
end
defp parse_name(name, %{strip_namespaces: true}) do
name
|> to_string
|> String.split(":")
|> List.last
|> Macro.underscore
|> String.to_atom
end
defp parse_name(name, _), do: name
end