-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.exs
84 lines (68 loc) · 1.93 KB
/
test.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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>
<template>
This test ensures anything inside this template tag is ignored entirely by the parser.
<script>s
food = "bar";
</script>
<template>
I could be a handlebars template or something, who knows :
</template>
</template>
</root>
"""
)
IO.inspect(doc)
Enum.each(XmlNode.all(doc, "//root/template"), fn(node) ->
IO.inspect(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("template")
|> XmlNode.text
)