我需要将 Clojure 数据结构序列化为 XML,但我对如何发出集合感到困惑。为了更具体,假设我有一个 Clojure 映射,如下所示:
(def parking-lot {:parking-lot #{
{:car {:color "red", :make "nissan", :year 2003}}
{:car {:color "blue", :make "toyota", :year 2001}}
{:car {:color "black", :make "honda", :year 2010}}}})
这只是一张地图,其中一个元素的值是一组“汽车”项目。现在,假设我想序列化这个映射以生成以下 XML:
<? xml version="1.0" ?>
<parking-lot>
<car color="red" make="nissan" year="2003" />
<car color="blue" make="toyota" year="2001" />
<car color="black" make="black" year="2010" />
</parking-lot>
在网上搜索有关如何在 Clojure 中最好地解析/发出 XML 的文档使我找到了clojure.data.xml库,这就是我正在使用的。
这是一个关于如何使用 clojure.data.xml 发出一些 XML 的简单示例:
REPL> (use 'clojure.data.xml)
=> nil
REPL> (emit-str (element :parking-lot {}))
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<parking-lot></parking-lot>"
一个稍微复杂一点的例子:
REPL> (emit-str (element :parking-lot {}
(element :car {:color "yellow" :make "ford" :year "2000"})
(element :car {:color "purple" :make "chevrolet" :year "1977"})))
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<parking-lot>
<car color=\"yellow\" year=\"2000\" make=\"ford\"></car>
<car color=\"purple\" year=\"1977\" make=\"chevrolet\"></car>
</parking-lot>"
在这里,您看到“元素”函数的第三个参数确实可以是对“元素”的可变数量的调用。在没有深入查看“元素”函数的文档的情况下,我想我假设“元素”将被重载,以将一系列元素项作为其第三个参数。因此,没有查看文档,我只是继续编写了一小段代码来做到这一点:
REPL> (emit-str (element :parking-lot {}
(map (fn [car] (let [carattrs (:car car)]
(element :car {:color (:color carattrs),
:make (:make carattrs),
:year (:year carattrs)})))
(:parking-lot parking-lot))))
我希望这会奏效,但可惜它没有。问题是“元素”函数的第三个参数不能是序列本身。
所以,在这一点上,我有点不知道该怎么做。我对 Lisp 和 Clojure 还是比较陌生,所以如果我的下一个想法是白痴,请放轻松。所以我的想法是,这会是宏的用例吗?即,我是否应该创建一个宏,将一组汽车(或任何 coll)作为其输入,并将其项目作为单独的 s 表达式输出?例如,我在想一个行为如下的宏:
REPL> (defmacro flatten-as-elements [coll-of-cars] ...)
REPL> (flatten-as-elements #{ {:color "blue" :model "honda" year "2000"}
{:color "yellow" :model "ford" year "2011"}})
=> (element :car {:color "blue" :model "honda" year "2000"})
(element :car {:color "yellow" :model "ford" year "2011"})
至少在我看来,这样一个宏的输出将适合作为“元素”函数的第三个参数,并且会产生我想要的目标。当然,我担心的是我忽略了一些完全明显的解决方案,并且在这里使用宏是被误导的。非常感谢 SO 社区的任何帮助!先感谢您!
-保罗