给定以下 xml,我如何延迟解析联系人记录? 目标是获取每个联系人元素的 xml 结构并将其传递给一个函数,该函数将处理将该记录导入到数据库中。
我将处理一个非常大的文件,并且希望避免将整个 xml 结构加载到内存中。
我之前已经使用 Stax 在 java 中完成了此操作,但我正在尝试弄清楚如何在 clojure 中执行类似的操作。
<?xml version="1.0"?>
<contact_list>
<contact id="1">
<first>Joe</first>
<last>Smith</last>
<email><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f993969cb99c81989489959cd79a9694" rel="noreferrer noopener nofollow">[email protected]</a></email>
</contact>
<contact id="2">
<first>Jane</first>
<last>Smith</last>
<email><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a101b141f3a1f021b170a161f54191517" rel="noreferrer noopener nofollow">[email protected]</a></email>
</contact>
<contact id="3">
<first>John</first>
<last>Smith</last>
<email><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5913363137193c21383429353c773a3634" rel="noreferrer noopener nofollow">[email protected]</a></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)))
最佳答案
这是 Clojure 最酷的功能之一 - xml/parse
返回的结果是一种惰性数据结构。它看起来就像“返回整个结构”,但它实际返回的内容利用了 Clojure 的惰性序列。
Lazy sequences是该语言的核心抽象之一(也是其主要优势之一)。
因此,Clojure 中不需要 SAX 或类似的东西 - 您可以同时获得 DOM 样式访问的易用性和 SAX 的效率。
就您而言,鉴于您的 <contact>
元素都是根 <contact_list>
的直接子元素元素,以下将为您提供一个延迟的联系人序列:
(:content (xml/parse (io/input-stream x)))
关于xml - 如何使用 clojure.data.xml 延迟解析输入流中的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25478704/