xml - 如何使用 clojure.data.xml 延迟解析输入流中的记录?

标签 xml clojure

给定以下 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/

相关文章:

javascript - 有人知道如何检测 Nativescript 的方向变化吗?

c# - 不能将 Descendants() 或 Elements() 与 xmlns 一起使用

javascript - 如何使用 ^ :export, 标记使用 `reify` 创建的方法,以便 Closure 编译器不重命名它们?

recursion - 更适合Common Lisp抽象来实现 "self recursive let"

java - 尝试将 XML 转换为允许用户输入的 JTable

c# - 需要一个按钮来在单击时更改其文本

Clojure:从文件中提取结构失败,字符串属性包含空格

clojure - Clojure 中的 PGobject 类型转换

xml - Go xml解码

clojure - 如何在 Datomic 中表示具有现有 UUID 的实体?