【发布时间】:2016-08-28 22:00:22
【问题描述】:
我正在使用 clojure.data.xml 解析来自 Stack Exchange 的一些 XML 数据,例如,如果我解析 Votes 数据,它会返回一个包含每行数据的 HashMap 的 LazySeq。
我要做的是为每一行获取仅与某些键关联的值,例如(get votes [:Id :CreationDate])。我尝试了很多事情,其中大多数导致铸造错误。
最接近我需要的是使用(doall (map get votes [:Id :CreationDate]))。但是,我现在遇到的问题是我似乎只能返回第一行(即(1 2011-01-19T00:00:00.000))
这是一个可以在任何 Clojure REPL 或 on Codepad online IDE 上运行的 MCVE。
理想情况下,我想返回某种集合或映射,其中包含每行所需的值,最终目标是写入 CSV 文件之类的文件。例如像
这样的地图(1 2011-01-19T00:00:00.000 2 2011-01-19T00:00:00.000 3 2011-01-19T00:00:00.000 4 2011-01-19T00:00:00.000)
(def votes '({:Id "1",
:PostId "2",
:VoteTypeId "2",
:CreationDate "2011-01-19T00:00:00.000"}
{:Id "2",
:PostId "3",
:VoteTypeId "2",
:CreationDate "2011-01-19T00:00:00.000"}
{:Id "3",
:PostId "1",
:VoteTypeId "2",
:CreationDate "2011-01-19T00:00:00.000"}
{:Id "4",
:PostId "1",
:VoteTypeId "2",
:CreationDate "2011-01-19T00:00:00.000"}))
(println (doall (map get votes [:Id :CreationDate])))
附加细节:如果这有任何帮助/兴趣,我用来获取上述惰性序列的代码如下:
(ns se-datadump.read-xml
(require
[clojure.data.xml :as xml])
(def xml-votes
"<votes><row Id=\"1\" PostId=\"2\" VoteTypeId=\"2\" CreationDate=\"2011-01-19T00:00:00.000\" /> <row Id=\"2\" PostId=\"3\" VoteTypeId=\"2\" CreationDate=\"2011-01-19T00:00:00.000\" /> <row Id=\"3\" PostId=\"1\" VoteTypeId=\"2\" CreationDate=\"2011-01-19T00:00:00.000\" /> <row Id=\"4\" PostId=\"1\" VoteTypeId=\"2\" CreationDate=\"2011-01-19T00:00:00.000\" /></votes>")
(defn se-xml->rows-seq
"Returns LazySequence from a properly formatted XML string,
which contains a HashMap for every <row> element with each of its attributes.
This assumes the standard Stack Exchange XML format, where a parent element contains
only a series of <row> child elements with no further hierarchy."
[xml-str]
(let [xml-records (xml/parse-str xml-str)]
(map :attrs (-> xml-records :content))))
; this returns a map identical as in the MCVE:
(def votes (se-xml->rows-seq xml-votes)
【问题讨论】:
-
我不确定我是否完全理解您的意图。您能否提供手动创建的示例结果?比说起来更容易。
-
@AntonHarald 我添加了一个示例期望结果,希望这有助于使其更清晰。
标签: clojure hashmap lazy-sequences