63 lines
1.2 KiB
Elixir
63 lines
1.2 KiB
Elixir
defmodule LastFm.Session do
|
|
require Record
|
|
|
|
defstruct [:name, :key, :pro]
|
|
|
|
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 parse(xml_string) do
|
|
doc = scan(xml_string)
|
|
|
|
name =
|
|
doc
|
|
|> first("//lfm/session/name")
|
|
|> text()
|
|
|
|
key =
|
|
doc
|
|
|> first("//lfm/session/key")
|
|
|> text()
|
|
|
|
subscriber =
|
|
doc
|
|
|> first("//lfm/session/subscriber")
|
|
|> text()
|
|
|
|
%__MODULE__{
|
|
name: name,
|
|
key: key,
|
|
pro: subscriber == "1"
|
|
}
|
|
end
|
|
|
|
defp scan(xml_string) do
|
|
{doc, []} =
|
|
xml_string
|
|
|> :binary.bin_to_list()
|
|
|> :xmerl_scan.string(quiet: true)
|
|
|
|
doc
|
|
end
|
|
|
|
defp first(node, path), do: node |> xpath(path) |> take_one
|
|
|
|
defp take_one([head | _]), do: head
|
|
defp take_one(_), do: nil
|
|
|
|
defp xpath(nil, _), do: []
|
|
|
|
defp xpath(node, path) do
|
|
:xmerl_xpath.string(to_charlist(path), node)
|
|
end
|
|
|
|
def text(node), do: node |> xpath(~c"./text()") |> extract_text
|
|
|
|
defp extract_text([xmlText(value: value)]), do: List.to_string(value)
|
|
defp extract_text(_x), do: nil
|
|
end
|