Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Last active July 26, 2023 10:07
Show Gist options
  • Star 35 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save sasa1977/5967224 to your computer and use it in GitHub Desktop.
Save sasa1977/5967224 to your computer and use it in GitHub Desktop.
Simple xmerl usage demo in Elixir
defmodule XmlNode do
require Record
Record.defrecord :xmlAttribute, Record.extract(:xmlAttribute, from_lib: "xmerl/include/xmerl.hrl")
Record.defrecord :xmlText, Record.extract(:xmlText, from_lib: "xmerl/include/xmerl.hrl")
def from_string(xml_string, options \\ [quiet: true]) do
{doc, []} =
xml_string
|> :binary.bin_to_list
|> :xmerl_scan.string(options)
doc
end
def all(node, path) do
for child_element <- xpath(node, path) do
child_element
end
end
def first(node, path), do: node |> xpath(path) |> take_one
defp take_one([head | _]), do: head
defp take_one(_), do: nil
def node_name(nil), do: nil
def node_name(node), do: elem(node, 1)
def attr(node, name), do: node |> xpath('./@#{name}') |> extract_attr
defp extract_attr([xmlAttribute(value: value)]), do: List.to_string(value)
defp extract_attr(_), do: nil
def text(node), do: node |> xpath('./text()') |> extract_text
defp extract_text([xmlText(value: value)]), do: List.to_string(value)
defp extract_text(_x), do: nil
defp xpath(nil, _), do: []
defp xpath(node, path) do
:xmerl_xpath.string(to_char_list(path), node)
end
end
doc = XmlNode.from_string(
"""
<root>
<child id="1">Saša</child>
<child id="2">Jurić</child>
</root>
"""
)
Enum.each(XmlNode.all(doc, "//child"), fn(node) ->
IO.puts "#{XmlNode.node_name(node)} id=#{XmlNode.attr(node, "id")} text=#{XmlNode.text(node)}"
end)
IO.puts(
doc
|> XmlNode.first("//child[@id='2']")
|> XmlNode.text
)
IO.puts(
doc
|> XmlNode.first("//child[@id='3']")
|> XmlNode.text
)
IO.puts(
doc
|> XmlNode.first("//root")
|> XmlNode.first("child[@id='1']")
|> XmlNode.text
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment