Current section

Files

Jump to
elixir_feed_parser lib xml_node.ex
Raw

lib/xml_node.ex

defmodule ElixirFeedParser.XmlNode do
# see https://github.com/erlang/otp/blob/maint/lib/xmerl/include/xmerl.hrl
# for Record definitions of xmlElement, xmlAttribute, xmlText
def parse_string(xml_string, options \\ [quiet: true]) do
{doc, []} = xml_string |> :binary.bin_to_list |> :xmerl_scan.string(options)
doc
end
def find(node, path) do
xpath(node, path) |> List.first
end
def map_children(node, selector, callback) do
node |> children(selector) |> Enum.map(callback)
end
def children(node, selector) do
node |> xpath("./#{selector}")
end
def attr(nil, _name), do: nil
def attr(node, name) do
node |> xpath("./@#{name}") |> extract_attr
end
defp extract_attr(nil), do: nil
defp extract_attr([]), do: []
defp extract_attr([{:xmlAttribute, _name, _expanded_name, _nsinfo, _namespace, _parents, _pos, _language, value, _normalized}]) do
List.to_string(value)
end
def text(node) do
node |> xpath("./text()") |> extract_text
end
defp extract_text(nil), do: nil
defp extract_text([]), do: nil
defp extract_text({:xmlText, _parents, _pos, _language, value, _type}) do
List.to_string(value)
end
defp extract_text([head | tail]) do
"#{extract_text(head)}#{extract_text(tail)}"
end
def xpath(nil, path), do: nil
def xpath(node, path) do
:xmerl_xpath.string(to_char_list(path), node)
end
def namespace(nil), do: nil
def namespace({:xmlElement, _name, _expanded_name, _nsinfo, {:xmlNamespace, default, _nodes}, _parents, _pos, _attributes, _content, _language, _xmlbase, _elementdef}) do
Atom.to_string(default)
end
end