odeac
How to parse sub-element list with SweetXml?
I have to parse an XML with the following structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root >
<node id="1"/>
<node id="2"/>
</root>
And I have tried the following approache based on xpath:
def parse_root(root_xml) do
root_xml
|> xpath(~x"//root",
nodes: ~x"./node"l |> transform_by(&parse_node/1)
)
end
def parse_node(node_xml) do
node_xml
|> xpath(~x"node", id: ~x"@id")
end
test "parse root" do
xml = """
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root >
<node id="1"/>
<node id="2"/>
</root>
"""
assert %{
nodes: [
%{id: "id1"},
%{id: "id2"}
]
} == parse_root(xml)
end
This fails with the following runtime error:
2) test parse root (TestSweet)
test/sweet_test.exs:172
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a bitstring
code: } == parse_root(xml)
stacktrace:
:erlang.byte_size({:xmlElement, :node, :node, [], {:xmlNamespace, [], []}, [root: 1], 2, [{:xmlAttribute, :id, [], [], [], [node: 2, root: 1], 1, [], ~c"1", false}], [], [], ~c"/Users/ovi/work/eb/playground", :undeclared})
(sweet_xml 0.7.4) lib/sweet_xml.ex:834: SweetXml.split_last_whitespace/1
(sweet_xml 0.7.4) lib/sweet_xml.ex:825: anonymous fn/2 in SweetXml.split_by_whitespace/1
(elixir 1.15.7) lib/stream.ex:990: Stream.do_transform_user/6
(sweet_xml 0.7.4) lib/sweet_xml.ex:788: anonymous fn/4 in SweetXml.continuation_opts/2
(xmerl 1.3.31) xmerl_scan.erl:571: :xmerl_scan.scan_document/2
(xmerl 1.3.31) xmerl_scan.erl:294: :xmerl_scan.string/2
(sweet_xml 0.7.4) lib/sweet_xml.ex:296: SweetXml.do_parse/2
(sweet_xml 0.7.4) lib/sweet_xml.ex:281: SweetXml.parse/2
(sweet_xml 0.7.4) lib/sweet_xml.ex:610: SweetXml.xpath/3
(sweet_xml 0.7.4) lib/sweet_xml.ex:642: SweetXml.xpath/3
(sweet_xml 0.7.4) lib/sweet_xml.ex:737: anonymous fn/3 in SweetXml.xmap/3
(elixir 1.15.7) lib/map.ex:957: Map.get_and_update/3
(sweet_xml 0.7.4) lib/sweet_xml.ex:737: SweetXml.xmap/3
test/sweet_test.exs:187: (test)
I also tried to parse the same XML using xmap as you can see below:
def parse_root2(root_xml) do
root_xml
|> xmap(~x"//root",
nodes: [
~x"./node",
id: ~x"@id"
]
)
end
test "parse root 2" do
xml = """
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root >
<node id="1"/>
<node id="2"/>
</root>
"""
assert %{
nodes: [
%{id: "id1"},
%{id: "id2"}
]
} == parse_root2(xml)
end
…and it fails with the following error:
1) test parse root 2 (TestSweet)
test/sweet_test.exs:200
** (FunctionClauseError) no function clause matching in SweetXml.xmap/3
The following arguments were given to SweetXml.xmap/3:
# 1
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\n<root >\n <node id=\"1\"/>\n <node id=\"2\"/>\n</root>\n"
# 2
%SweetXpath{path: ~c"//root", is_value: true, is_list: false, is_keyword: false, is_optional: false, cast_to: false, transform_fun: &SweetXpath.Priv.self_val/1, namespaces: []}
# 3
[nodes: [%SweetXpath{path: ~c"./node", is_value: true, is_list: false, is_keyword: false, is_optional: false, cast_to: false, transform_fun: &SweetXpath.Priv.self_val/1, namespaces: []}, {:id, %SweetXpath{path: ~c"@id", is_value: true, is_list: false, is_keyword: false, is_optional: false, cast_to: false, transform_fun: &SweetXpath.Priv.self_val/1, namespaces: []}}]]
Attempted function clauses (showing 6 out of 6):
def xmap(nil, _, %{is_optional: true})
def xmap(parent, [], atom) when is_atom(atom)
def xmap(_, [], %{is_keyword: false})
def xmap(_, [], %{is_keyword: true})
def xmap(parent, [{label, spec} | tail], is_keyword) when is_list(spec)
def xmap(parent, [{label, sweet_xpath} | tail], is_keyword)
code: } == parse_root2(xml)
stacktrace:
(sweet_xml 0.7.4) lib/sweet_xml.ex:721: SweetXml.xmap/3
test/sweet_test.exs:215: (test)
Any suggestions will be highly appreciated.
Thanks in advance!
Marked As Solved
Hermanverschooten
I tried this in a livebook.
import SweetXml
xml = """
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root >
<node id="1"/>
<node id="2"/>
</root>
"""
xml
|> xpath(~x"//root", nodes: [~x"./node"l, id: ~x"@id"i])
%{nodes: [%{id: 1}, %{id: 2}]}
xml
|> xpath(~x"//root", nodes: [~x"./node"l, id: ~x"@id"s |> transform_by(fn x -> "id" <> x end)])
%{nodes: [%{id: "id1"}, %{id: "id2"}]}
2
Popular in Questions
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
As a follow up to my earlier question:
I have the code compiling and running but not getting a successful login from the rest server. ...
New
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
I tried installing
elixir 1.11.2
erlang 23.3.4
via asdf in my zsh shell. Enabled the versions locally and globally.
When I list them ...
New
Hello everybody,
usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Hi,
I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Hi all
I want to have a unix time, from the current time plus 1 hour.
DateTime.now + 1 hour
How to get it in elixir?
Thanks
New
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors:
[WARN] - (starship::utils): Executing command ...
New
Other popular topics
Update:
How to use the Blogs & Podcasts section
You can post links to your blog posts or podcasts either in one of the Official Blog...
New
Hi! May someone helps me, please!
I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!)
This post collects co...
New
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
by Lance Halvorsen
Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New







