概要
paiza.ioでelixirやってみた。
xmerl使ってみた。
サンプルコード
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">ai</child>
<child id="2">ue</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
)
実行結果
child id=1 text=ai
child id=2 text=ue
ue
ai
成果物
以上。