clojure data.xml强制计算惰性xml树

clojure data.xml强制计算惰性xml树,clojure,Clojure,根据的自述文件,parse返回的数据结构包含惰性序列。因此 (with-open [r (io/input-stream (io/file "data.xml"))] (xml/parse r)) 可能在遍历此代码块外的树时引发异常,因为输入流已关闭 返回之前强制评估整棵树的最优雅方式是什么?我尝试了以下方法,但我想知道是否有更简单的方法 (with-open [r (io/input-stream (io/file "data.xml"))]

根据的自述文件,
parse
返回的数据结构包含惰性序列。因此

(with-open [r (io/input-stream (io/file "data.xml"))]
  (xml/parse r))
可能在遍历此代码块外的树时引发异常,因为输入流已关闭

返回之前强制评估整棵树的最优雅方式是什么?我尝试了以下方法,但我想知道是否有更简单的方法

(with-open [r (io/input-stream (io/file "data.xml"))]
  (doto (xml/parse r)
    (->> (tree-seq map? :content) (dorun))))

对于一般的XML解析,我可以建议。它不是惰性的,并且简化了XML数据的加载。还有类似的名称空间用于解析,还有

对于一般用途,您始终可以回退到。它将递归地遍历一个数据结构,并将每个项目转换为一个普通的映射、向量、集合等。它还将通过
slurp
实现
InputStream
(非常方便地测试返回
InputStream
而不是字符串的http端点)。它还处理
java.lang.Iterable
=>向量。总的来说,
unlazy
就像
doall
服用类固醇一样


旁白:


如果您想知道map&set之类的东西,那是因为Datomic返回值的行为类似于一个“惰性映射”,并且不会实现它们的所有键值对,除非您专门将每个键提取出来,或者通过
或类似的方式将对象转储到常规Clojure映射中。

对于一般的XML解析,我可能会建议。它不是惰性的,并且简化了XML数据的加载。还有类似的名称空间用于解析,还有

对于一般用途,您始终可以回退到。它将递归地遍历一个数据结构,并将每个项目转换为一个普通的映射、向量、集合等。它还将通过
slurp
实现
InputStream
(非常方便地测试返回
InputStream
而不是字符串的http端点)。它还处理
java.lang.Iterable
=>向量。总的来说,
unlazy
就像
doall
服用类固醇一样


旁白:


如果你想知道map&set之类的东西,那是因为Datomic返回值的行为就像一个“惰性映射”,除非你通过
或类似的方式特别提取每个键或将对象转储到一个常规Clojure映射中,否则不会实现它们的所有键值对。

使用
doall
强制实现惰性序列,然后只保留第一个元素。此外,您可以使用
xml-seq
而不是
tree-seq

(打开[r(io/输入流(io/文件“data.xml”))]
(->r xml/parse xml seq doall first))

使用
doall
强制实现惰性序列,然后只保留第一个元素。此外,您可以使用
xml-seq
而不是
tree-seq

(打开[r(io/输入流(io/文件“data.xml”))]
(->r xml/parse xml seq doall first))

此版本将整个未使用的序列保留在内存中,直到函数返回。这是非惰性序列的必要成本。注意,序列与所需的树共享其数据结构,因此成本可能不会太高。您需要衡量应用程序中的成本。如果内存成本太高,你需要改变策略,拥抱懒惰,而不是试图避免它。@erdos如果你想参与懒惰,您必须使用open
将工作移动到
中。此版本在函数返回之前将整个未使用的序列保留在内存中。这是非惰性序列的必要成本。注意,序列与所需的树共享其数据结构,因此成本可能不会太高。您需要衡量应用程序中的成本。如果内存成本太高,你需要改变策略,接受懒惰,而不是试图避免它。@erdos如果你想参与懒惰,你必须用open
将工作转移到你的
中。