我有一個需要將Clojure數據結構序列化爲XML,但我絆倒如何發出一個集合。爲了使這更具體,假設我有一個Clojure的地圖如下:使用clojure.data.xml從Clojure發送XML。
(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來說還是比較新的,所以如果我的下一個想法是虛無go go的,那就輕鬆點。所以我的想法是,這是一個宏的用例嗎?也就是說,我是否應該創建一個宏作爲其輸入的一個集合(或任何關於該事件的集合)的汽車,並將其作爲單獨的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社區的任何幫助!先謝謝你!
- 保羅