您拥有的数据是 Enlive 格式的。用于clojure.pprint/pprint
查看更好的格式:
{:tag :Vehicle,
:attrs nil,
:content
[{:tag :Model, :attrs nil, :content ["Toyota"]}
{:tag :Color, :attrs nil, :content ["Red"]}
{:tag :Loans,
:attrs nil,
:content
[{:tag :Reoccuring, :attrs nil, :content ["Monthly"]}
{:tag :Owners,
:attrs nil,
:content [{:tag :Owner, :attrs nil, :content ["Bob"]}]}]}
{:tag :Tires,
:attrs nil,
:content
[{:tag :Model, :attrs nil, :content ["123123"]}
{:tag :Size, :attrs nil, :content ["23"]}]}
{:tag :Engine,
:attrs nil,
:content [{:tag :Model, :attrs nil, :content ["30065"]}]}]}
问题是您想要的输出实际上不是合法的 EDN 数据格式。但是,您可以使用该tupelo.forest
库在多种数据格式之间进行转换:
首先声明数据并解析成Enlive格式:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.parse.xml :as xml]
[tupelo.forest :as tf])
)
(def xml-str
"<Vehicle>
<Model>Toyota</Model>
<Color>Red</Color>
<Loans>
<Reoccuring>Monthly</Reoccuring>
<Owners>
<Owner>Bob</Owner>
</Owners>
</Loans>
<Tires>
<Model>123123</Model>
<Size>23</Size>
</Tires>
<Engine>
<Model>30065</Model>
</Engine>
</Vehicle> ")
验证结果
(dotest
(let [data-enlive (xml/parse xml-str)]
(is= data-enlive
{:tag :Vehicle,
:attrs {},
:content [{:tag :Model, :attrs {}, :content ["Toyota"]}
{:tag :Color, :attrs {}, :content ["Red"]}
{:tag :Loans,
:attrs {},
:content [{:tag :Reoccuring, :attrs {}, :content ["Monthly"]}
{:tag :Owners,
:attrs {},
:content [{:tag :Owner, :attrs {}, :content ["Bob"]}]}]}
{:tag :Tires,
:attrs {},
:content [{:tag :Model, :attrs {}, :content ["123123"]}
{:tag :Size, :attrs {}, :content ["23"]}]}
{:tag :Engine,
:attrs {},
:content [{:tag :Model, :attrs {}, :content ["30065"]}]}]})
转换为打嗝格式:
(is= (tf/enlive->hiccup data-enlive)
[:Vehicle
[:Model "Toyota"]
[:Color "Red"]
[:Loans [:Reoccuring "Monthly"]
[:Owners [:Owner "Bob"]]]
[:Tires [:Model "123123"]
[:Size "23"]]
[:Engine [:Model "30065"]]])
您可能还喜欢“灌木”格式:
(is= (tf/enlive->bush data-enlive)
[{:tag :Vehicle}
[{:tag :Model, :value "Toyota"}]
[{:tag :Color, :value "Red"}]
[{:tag :Loans}
[{:tag :Reoccuring, :value "Monthly"}]
[{:tag :Owners} [{:tag :Owner, :value "Bob"}]]]
[{:tag :Tires}
[{:tag :Model, :value "123123"}]
[{:tag :Size, :value "23"}]]
[{:tag :Engine} [{:tag :Model, :value "30065"}]]])
或更详细的“树”格式
(is= (tf/enlive->tree data-enlive)
{:tag :Vehicle,
:tupelo.forest/kids
[{:tag :Model, :value "Toyota", :tupelo.forest/kids []}
{:tag :Color, :value "Red", :tupelo.forest/kids []}
{:tag :Loans,
:tupelo.forest/kids
[{:tag :Reoccuring, :value "Monthly", :tupelo.forest/kids []}
{:tag :Owners,
:tupelo.forest/kids
[{:tag :Owner, :value "Bob", :tupelo.forest/kids []}]}]}
{:tag :Tires,
:tupelo.forest/kids
[{:tag :Model, :value "123123", :tupelo.forest/kids []}
{:tag :Size, :value "23", :tupelo.forest/kids []}]}
{:tag :Engine,
:tupelo.forest/kids
[{:tag :Model, :value "30065", :tupelo.forest/kids []}]}]})
))
有关完整信息,请参阅Tupelo Forest 文档
。
上面的代码是使用这个模板项目运行的。
如果您正在寻找分层地图样式的输出,您可以将这样的东西拼凑在一起:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require [clojure.walk :as walk]))
(dotest
(let [data [:Vehicle
[:Model "Toyota"]
[:Color "Red"]
[:Loans
[:Reoccuring "Monthly"]
[:Owners
[:Owner "Bob"]]]
[:Tires
[:Model "123123"]
[:Size "23"]]
[:Engine
[:Model "30065"]]]
mappy (walk/postwalk
(fn [item]
(if (vector? item)
(if (= 2 (count item))
(conj {} item)
{(first item)
(into {} (rest item))})
item))
data)]
有测试
(is= mappy
{:Vehicle
{:Model "Toyota",
:Color "Red",
:Loans {:Reoccuring "Monthly"
:Owners {:Owner "Bob"}},
:Tires {:Model "123123"
:Size "23"},
:Engine {:Model "30065"}}})))
虽然这是非常脆弱的书面。