Elixir中XML转JSON问题:Sweetyxml及xmerl解析未得到预期结果
实现步骤
你需要先在项目中引入JSON序列化依赖,在mix.exs的deps配置中添加:
defp deps do [ {:jason, "~> 1.4"} ] end
执行mix deps.get安装依赖后,使用如下完整代码即可完成转换:
defmodule XmlToJson do # 提取XML节点文本内容 defp get_node_text([]), do: "" defp get_node_text([{:xmlText, _, _, _, text, :text} | _]) do to_string(text) |> String.trim() end defp get_node_text([_ | rest]), do: get_node_text(rest) # 类型转换:把文本值转为对应JSON类型 defp convert_type(""), do: "" defp convert_type("true"), do: true defp convert_type("false"), do: false defp convert_type(val) do cond do String.match?(val, ~r/^\d+$/) -> String.to_integer(val) String.match?(val, ~r/^\d+\.\d+$/) -> num = String.to_float(val) if num == trunc(num), do: trunc(num), else: num true -> val end end def run(file_path) do # 读取解析XML {:ok, xmldoc} = File.read(Path.expand(file_path)) {doc, []} = xmldoc |> to_charlist() |> :xmerl_scan.string() # 提取order节点下所有子节点 order_fields = for element <- doc.content, match?({:xmlElement, _, _, _, _, _, _, _, _, _, _, _}, element) do key = element.name |> to_string() value = element.content |> get_node_text() |> convert_type() {key, value} end |> Map.new() # 生成目标结构并转JSON %{"order" => order_fields} |> Jason.encode!(pretty: true) end end # 调用示例 XmlToJson.run("/Users/sohaibanwar/Desktop/unconfirmed_order.xml") |> IO.puts()
逻辑说明
- 针对
:xmerl_scan返回的标准XML节点结构,编写了专门的文本提取函数,自动处理空标签、嵌套内容的场景 - 类型转换函数会自动识别布尔值、整数、浮点数,其中
.00结尾的浮点数会自动转为整数,完全匹配要求的JSON格式 - 最终输出开启了
pretty: true参数,会直接生成格式化后的JSON字符串
内容的提问来源于stack exchange,提问作者Sohaib Anwaar
相关产品推荐
相关产品推荐

