考虑以下xml:
<Period>
<TimeInterval v="2010-06-20T21:00Z/2010-06-21T21:00Z"/>
<Resolution v="HOURLY"/>
<AccountInterval>
<Pos v="1"/>
<InQty v="0.0"/>
</AccountInterval>
<AccountInterval>
<Pos v="2"/>
<InQty v="0.0"/>
</AccountInterval>
<AccountInterval>
<Pos v="3"/>
<InQty v="0.0"/>
</AccountInterval>
</Period>我希望使用clojure.xml/parse解析XML后返回的数据结构“扁平化”。
{:content
[{:content nil,
:attrs {:v "2015-06-20T21:00Z/2015-06-21T21:00Z"},
:tag :TimeInterval}
{:content nil, :attrs {:v "PT1H"}, :tag :Resolution}
{:content
[{:content nil, :attrs {:v "1"}, :tag :Pos}
{:content nil, :attrs {:v "0.0"}, :tag :InQty}],
:attrs nil,
:tag :AccountInterval}
{:content
[{:content nil, :attrs {:v "2"}, :tag :Pos}
{:content nil, :attrs {:v "0.0"}, :tag :InQty}],
:attrs nil,
:tag :AccountInterval}
{:content
[{:content nil, :attrs {:v "3"}, :tag :Pos}
{:content nil, :attrs {:v "0.0"}, :tag :InQty}],
:attrs nil,
:tag :AccountInterval}],
:attrs nil,
:tag :Period}若要获得这类向量:
["2010-06-20T21:00Z/2010-06-21T21:00Z" "HOURLY" 1 0.0 2 0.0 3 0.0]我如何在clojure中使用core.match来实现这一点?
发布于 2015-07-06 10:17:06
您可以使用一个非常简单的递归函数来完成这个任务:
(defn flatten-xml
[{:keys [attrs content]}]
(if-let [v (:v attrs)]
[v]
(mapcat flat-xml content)))因此,如果您有一个具有解析的XML数据的data变量,您可以使用这个flatten-xml函数将其扁平化:
(flatten-xml data)
; => ("2015-06-20T21:00Z/2015-06-21T21:00Z" "PT1H" "1" "0.0" "2" "0.0" "3" "0.0")发布于 2015-07-06 12:43:14
另一种方法是:
(defn flatten-bfs [{:keys [attrs content]}]
(loop [ret [], queue (into clojure.lang.PersistentQueue/EMPTY content)]
(if (seq queue)
(let [{attrs :attrs children :content} (peek queue)]
(recur (if (nil? (:v attrs)) ret (conj ret (:v attrs))) (into (pop queue) children))
)
ret
)
)
)https://stackoverflow.com/questions/31242478
复制相似问题