Generic xml traversal.
Brian Lonsdorf
brian@REDACTED
Thu Aug 19 19:04:58 CEST 2010
I apologize if this is a repost for some, I think I posted it in some old buried thread by accident yesterday.
Hi everyone! I'm very excited to be starting my erlang journey, but I've been stuck on this for a few days now.
I'm trying to create key, value pair tuples out of xml. I'd like to make a list out of nested xml too. For instance:
<something>
<Item>
<name>The Name!</name>
<reviews>
<review>
<review-by>WE</review-by>
<review-points>92</review-points>
</review>
<review>
<review-by>WS</review-by>
<review-points>90</review-points>
</review>
</reviews>
</Item>
</something>
Should turn out like:
[{"name", "The Name!"}, {"reviews", [{"review-by", "WE"}, {"review-points", 92}], {"review-by", "WS"}, {"review-points", 90}]} ]
Where Item is my main node that i want to get lists of.
I've admittedly cargo culted and tweaked the code below. It only returns a list of the first Item's elements. And I'm not sure how to begin the nested ones.
Thanks so much!
-Brian
-----------------------------
-module(reader).
-compile(export_all).
-include_lib("xmerl/include/xmerl.hrl").
parse(FileName) ->
{Records,_} = xmerl_scan:file(FileName),
extract(Records, []).
extract(Record, Acc) when is_record(Record, xmlElement) ->
case Record#xmlElement.name of
'Item' ->
ItemData = lists:foldl(fun extract/2, [], Record#xmlElement.content),
[ {item, ItemData} | Acc ];
_ ->
lists:foldl(fun extract/2, Acc, Record#xmlElement.content)
end;
extract({xmlText, [{Attribute, _}, {'Item', 2}, _], _, _, Value, text}, Acc) ->
[{Attribute, Value}|Acc];
extract(_, Acc) ->
Acc.
-------------------------------
I've also seen this done with list comprehension. It's beautiful, but i can't get it to nest:
parse(FileName) ->
{#xmlElement{content=Item}, _} = xmerl_scan:file(FileName),
[{Tag, Val} ||
#xmlElement{content=Query} <- Item,
#xmlElement{content=Fields} <- Query,
#xmlText{parents=[{Tag, _} | _], value=Val} <- Fields].
More information about the erlang-questions
mailing list