defmodule JsonToXml do import XmlBuilder @moduledoc """ Documentation for JsonToXml. """ @doc """ Converts the given json string into a xml string. The document root is added with the tag ``. Elements in arrays are wrapped in `` tags like so: ``` json { "list": ["apple", "banana"] } ``` is converted to ``` xml apple banana ``` ## Examples iex>JsonToXml.convert(~s({ "firstname": "john", "lastname": "doe" })) "\\n\\n\\tjohn\\n\\tdoe\\n" iex>JsonToXml.convert(~s({ "name": { "first": "john", "last": "doe" } })) "\\n\\n\\t\\n\\t\\tjohn\\n\\t\\tdoe\\n\\t\\n" iex>JsonToXml.convert(~s({ "person": { "name": "doe", "address": { "street": "Huffman Road", "number": "12"}} })) "\\n\\n\\t\\n\\t\\t
\\n\\t\\t\\t12\\n\\t\\t\\tHuffman Road\\n\\t\\t
\\n\\t\\tdoe\\n\\t
\\n
" iex>JsonToXml.convert(~s({ "list": ["apple", "banana", "lemon"] })) "\\n\\n\\t\\n\\t\\tapple\\n\\t\\tbanana\\n\\t\\tlemon\\n\\t\\n" """ def convert(json) do content = Poison.decode!(json) |> map_elements() XmlBuilder.doc("root", content) end @doc """ Converts the given json file into a xml string. ## Examples iex>JsonToXml.convert_file("test/fixtures/example.json") "\\n\\n\\t
\\n\\t\\t12\\n\\t\\tHuffman Road\\n\\t
\\n\\t\\n\\t\\tfirst\\n\\t\\t\\n\\t\\t\\tsweet\\n\\t\\t\\tindigestive\\n\\t\\t\\n\\t\\tlemon\\n\\t\\n\\tJohn Doe\\n
" """ def convert_file(file) do File.read!(file) |> convert() end defp map_elements(elements) do Enum.map(elements, &create_element/1) end defp create_element({key, value}) when is_map(value) do element(key, map_elements(value)) end defp create_element({key, value}) when is_binary(value) do element(key, value) end defp create_element({key, value}) when is_list(value) do array = Enum.reduce(value, [], &create_array_item/2) |> Enum.reverse() element(key, array) end defp create_array_item(element, acc) do [create_element({"element", element}) | acc] end end