如何使用clojure.data.xml从输入流中懒惰地解析记录?

时间:2014-08-25 03:38:37

标签: xml clojure

鉴于以下xml,我如何懒惰地解析联系人记录? 目标是获取每个联系人元素的xml结构,并将其传递给将处理该记录导入数据库的函数。

我正在处理一个非常大的文件,并希望避免将整个xml结构加载到内存中。

我之前在使用Stax的java中做过这个,但是我试图弄清楚如何在clojure中做类似的事情。

<?xml version="1.0"?>
<contact_list>
  <contact id="1">
    <first>Joe</first>
    <last>Smith</last>
    <email>joe@example.com</email>
  </contact>
  <contact id="2">
    <first>Jane</first>
    <last>Smith</last>
    <email>jane@example.com</email>
  </contact>
  <contact id="3">
    <first>John</first>
    <last>Smith</last>
    <email>John@example.com</email>
  </contact>
</contact_list>

现在我刚刚得到了下面的代码,它返回了整个结构。

(use '[clojure.data.xml :as xml])
(use '[clojure.java.io :as io])

(defn handle-contact 
  "Do something with a contact"
  [contact]
  (println contact)
)

(defn parse-contacts
  "Parse individual contact records"
  [x]
  (xml/parse (io/input-stream x)))

1 个答案:

答案 0 :(得分:2)

这是Clojure最酷的功能之一 - xml/parse返回的结果是一个懒惰的数据结构。 看起来喜欢它&#34;返回整个结构&#34;但实际上它的回归利用了Clojure的懒惰序列。

Lazy sequences是语言的核心抽象之一(也是其主要优势之一)。

因此,在Clojure中不需要SAX或类似的东西 - 您可以轻松使用DOM样式的访问和SAX的效率。

在您的情况下,鉴于您的<contact>元素都是根<contact_list>元素的直接子元素,以下内容将为您提供一系列懒惰的联系人:

(:content (xml/parse (io/input-stream x)))