Clojure中处理大型XML文件

13

我是Clojure的新手,我的第一个项目需要处理一个庞大的XML文件(250+GB)。我想把它放入PostgreSQL中以便以后处理,但不知道如何处理这么大的文件。


2
从理解如何处理小文件开始,然后逐步提高。 - Mongus Pong
6
这个 XML 是什么样子的?是高度树状的还是扁平化的许多项的集合? - cgrand
4个回答

20

我使用了新的clojure.data.xml库,在一台性能一般的笔记本上处理了一个31GB大小的维基百科转储文件。旧的lazy-xml贡献库无法工作(内存不足)。

https://github.com/clojure/data.xml

简化示例代码:

(require '[clojure.data.xml :as data.xml]) ;'

(defn process-page [page]
  ;; ...
  )

(defn page-seq [rdr]
  (->> (:content (data.xml/parse rdr))
       (filter #(= :page (:tag %)))
       (map process-page)))

那么这就是@ivant所指的吗?Clojure对于lazy-xml的IO实现出了什么问题? - andrew cooke
是的,它有问题。尽管如此,它是旧的Clojure Contrib的一部分,并已被弃用。data.xml是替代品。 - Justin Kramer
好的 - 我花了几个小时尝试所有可能的((()))组合,但没有成功。我遇到了堆栈溢出错误,我理解是因为我使用了这个:(with-open [rdr (BufferedReader. (FileReader. file-name))]而应该使用一些输入流,但我对Clojure还很陌生,在这几个小时之后...你能帮忙吗? - trzewiczek
3
抱歉,我忘了提到:我遇到了StackOverflow错误,这是由于Java上游bug引起的。解决方法是使用(data.xml/parse rdr :coalescing false),但目前只适用于data.xml的主分支。0.0.3版本没有:coalescing选项。 - Justin Kramer
2
成功地使用了维基百科的转储文件 - 很好。您需要将其包装在 with-opendorun 中,以便能够懒惰地通过大列表进行工作:(with-open [rdr (fn-that-opens-a-reader)] (dorun (->> ...与上述相同... - Korny
显示剩余2条评论

2

API 可能会懒惰,但 IO 不会,所以我怀疑它能否处理那么大的文件。 - ivant
2
@ivant 你需要将它连接到一个逐步读取数据的输入流。这是在Java中处理大型XML文件的标准做法。 - andrew cooke
请查看Justin的答案,了解ivant在此可能指的是什么。 - andrew cooke

0

您还可以使用expresso XML解析器处理大文件(www.expressoxml.com)。它可以解析36GB或更大的文件,因为它不受文件大小限制。它可以从搜索中返回多达230,000个元素,并且可以通过其网站上的“云”进行流式传输。最重要的是,他们的开发者版本是免费的。


3
尽管你没有试图把这则广告伪装成客观建议,但最好明确说明你与该产品的强烈关联。https://twitter.com/Lughnasagh/status/260387856772653056。 - Rob Grant

0

我也尝试过,但没有成功。我的意思是 - 它解决了大文件的问题,但我无法使用xpath查询获得结果 - 它返回空结果。唯一有效的xpath查询是“。”,但这不是我想要的... 我已经为此问题奋斗了两个多小时了... :( - trzewiczek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接