如何在 Erlang 中将 XML 转换为元组列表?
我正在尝试从 XML 创建键、值对元组。我想从任何嵌套的 XML 中列出一个列表。这似乎是一个很常见的事情,但我找不到任何例子。
例如:
<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>
应该是这样的:
[[{"name", "The Name!"}, {"reviews", [{"review-by", "WE"}, {"review-points", 92}], {"review-by", "WS"}, {"review-points", 90}]} ]]
其中每个 Item 都是主包装器节点。
诚然,我对货物崇拜并调整了下面的代码。它仅返回第一个 Item 的元素的列表。我不知道如何开始嵌套的。
-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'm trying to create key, value pair tuples out of XML. I'd like to make a list out of any nested XML. It seems like a very common thing to do, but I can't find any examples.
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 each Item is the main wrapper node.
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.
-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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试一下Erlsom。函数“erlsom:simple_form(XML)”将为您提供 {Node,Attrib,Value}:
但是,如果您想删除属性,那么您可以编写一个 fun 来传递给 erlsom SAX 解析器或重新格式化 simple_form 的输出。像这样的东西(重新格式化输出):
这将产生以下输出:
注意,我还没有在非常大的 XML 文件上测试过这个。您应该运行一些测试并考虑内存问题。
Give Erlsom a try. The Function "erlsom:simple_form(XML)" will give you {Node,Attrib,Value}:
However, if you want to drop the Attributes then you can write a fun to pass to the erlsom SAX parser or reformat the output of simple_form. Something like this (to reformat output):
This would produce the following output:
Note, I haven't tested this on very large XML files. You should run a few tests and consider mem issues.