Я разбираю некоторые данные XML из Stack Exchange с помощью clojure.data.xml
, например, если я разбираю данные Votes, он возвращает LazySeq, содержащий HashMap для каждой строки данных.Выполнять «получить» на всех элементах HashMap в LazySeq
То, что я пытаюсь сделать, это получить значения, связанные только с определенными ключами, для каждой строки, например, (get votes [:Id :CreationDate])
. Я пробовал много вещей, большинство из которых приводят к ошибкам.
Ближайший я мог бы добраться до того, что мне нужно, используя (doall (map get votes [:Id :CreationDate]))
. Тем не менее, проблема, которую я испытываю сейчас, что я не могу вернуть больше, чем просто в первой строке (т.е. (1 2011-01-19T00:00:00.000)
)
Вот MCVE, которая может быть запущена на любом Clojure REPL или on Codepad online IDE.
В идеале я хотел бы вернуть какую-то коллекцию или карту, которая содержит значения, которые мне нужны для каждой строки, конечная цель - написать что-то вроде файла 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])))
Дополнительная деталь: Если это какой-либо помощи/интерес, код, я использую, чтобы получить над ленивым SEQ выглядит следующим образом:
(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 Я добавил пример желаемого результата, надеюсь, что это поможет сделать его более понятным. – Phrancis