ClojureのXMLのジッパーを使用して複数の値を返します
質問
は、私たちがそうのようないくつかのXMLがあるとしましょます:
<a>
<b>
<c>text</c>
<d>
<e>text</e>
<f>
... lots of cruft here ..
</f>
</d>
</b>
<b>
...
</b>
<!-- more b sub-trees -->
</a>
さて、zip_filter / xml.cljのサンプルを見て、私は私がに興味が単一の値を取得する方法を考え出したています。
私は(C電子)のテキスト値のペアのリストを返すような何かをするだろうかと思いまして。
EDITます:
ここではいくつかの作業コードですが、それはかなり醜いです。些細なリファクタリングを求め、これを行うにはジッパーが私たちを与えるよりよい方法はありませんか?
(defn extract-data [xml]
(let [items (x/xml-> xml zf/descendants :Item) ;items not top-level
getAttributes #(x/xml1-> % :ItemAttributes) ;items have itemattributes
getASIN #(x/xml1-> % :ASIN x/text) ;items have ASINs
getTitle #(x/xml1-> % :Title x/text) ;itemattributes have Titles
getAuthor #(x/xml1-> % :Author x/text)] ;itemattributes have Authors
(map
;build a function to get everything we need from the items, and apply
#(let [attributes (getAttributes %)] ;get the attributes, we'll use it twice
(list
(getASIN %)
(getTitle attributes)
(getAuthor attributes)))
items)))
解決
は、使用Clojureのバージョンによっては、juxt
機能が役立つかもしれません。あなたの投稿コード(関連部分のみ):
(defn extract-data
[xml]
(let [...]
(map (juxt getASIN (comp getTitle getAttributes) (comp getAuthor getAttributes)) items))))
他のヒント
私は、よりよい方法はあり確信しているが、これは仕事をしていません。
(letfn [(get-tag [tag coll] (:content (first (filter #(= tag (:tag %)) coll))))]
(map #(list (get-tag :c %) (get-tag :e (get-tag :d %)))
(map :content (:content (clojure.xml/parse "foo.xml")))))
で結果
((["ctext1"] ["etext1"]) (["ctext2"] ["etext2"]))
所属していません StackOverflow