gpt4 book ai didi

xml - Clojure XML 流关闭异常

转载 作者:数据小太阳 更新时间:2023-10-29 02:07:48 25 4
gpt4 key购买 nike

我在使用 clojure.data.xml 解析 XML 文件时遇到异常,因为在解析完成之前流正在关闭。

我不明白的是为什么 doallwith-open 关闭它之前不强制评估 XML 数据(如 this related answer 所建议):

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

(defn file->xml [path]
(with-open [rdr (-> path io/resource io/reader)]
(doall (xml/parse rdr))))

抛出异常:

(file->xml "example.xml")
;-> XMLStreamException ParseError at [row,col]:[80,1926]
Message: Stream closed com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next

如果我删除 with-open 包装器,它会按预期返回 XML 数据(因此文件是合法的,但不能保证读取器已关闭)。

我看到 (source xml/parse) 产生惰性结果:

(defn parse
"Parses the source, which can be an
InputStream or Reader, and returns a lazy tree of Element records.
Accepts key pairs with XMLInputFactory options, see http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html
and xml-input-factory-props for more information.
Defaults coalescing true."
[source & opts]
(event-tree (event-seq source opts)))

所以这也许是相关的,但我的功能与 clojure.data.xml README 上的“往返”示例非常相似.

我在这里错过了什么?

最佳答案

我很惊讶地看到这种行为。 clojure.data.xml.Element(返回类型)似乎实现了一种不受 doall 影响的“惰性映射”。

这是一个将惰性值转换为法线贴图的解决方案:

(ns tst.clj.core
(:use clj.core clojure.test tupelo.test)
(:require
[tupelo.core :as t]
[clojure.string :as str]
[clojure.pprint :refer [pprint]]
[clojure.java.io :as io]
[clojure.data.xml :as xml]
[clojure.walk :refer [postwalk]]
))
(t/refer-tupelo)

(defn unlazy
[coll]
(let [unlazy-item (fn [item]
(cond
(sequential? item) (vec item)
(map? item) (into {} item)
:else item))
result (postwalk unlazy-item coll) ]
result ))

(defn file->xml [path]
(with-open [rdr (-> path io/resource io/reader) ]
(let [lazy-vals (xml/parse rdr)
eager-vals (unlazy lazy-vals) ]
eager-vals)))
(pprint (file->xml "books.xml"))

{:tag :catalog,
:attrs {},
:content
[{:tag :book,
:attrs {:id "bk101"},
:content
[{:tag :author, :attrs {}, :content ["Gambardella, Matthew"]}
{:tag :title, :attrs {}, :content ["XML Developer's Guide"]}
{:tag :genre, :attrs {}, :content ["Computer"]}
{:tag :price, :attrs {}, :content ["44.95"]}
{:tag :publish_date, :attrs {}, :content ["2000-10-01"]}
{:tag :description,
:attrs {},
:content
["An in-depth look at creating applications\n with XML."]}]}
{:tag :book,
:attrs {:id "bk102"},
:content
[{:tag :author, :attrs {}, :content ["Ralls, Kim"]}
{:tag :title, :attrs {}, :content ["Midnight Rain"]}
{:tag :genre, :attrs {}, :content ["Fantasy"]}
{:tag :price, :attrs {}, :content ["5.95"]}
{:tag :publish_date, :attrs {}, :content ["2000-12-16"]}
{:tag :description,
:attrs {},
:content
["A former architect battles corporate zombies,\n an evil sorceress, and her own childhood to become queen\n of the world."]}]}
{:tag :book,
:attrs {:id "bk103"},
:content .....

由于 clojure.data.xml.Element 实现了 clojure.lang.IPersistentMap,使用 (map? item) 返回 true。

这是 sample data for books.xml

请注意:

clojure.data.xmlclojure.xml 不同。您可能需要探索这两个库以找到最适合您需求的库。

您还可以在需要时使用 crossclj.info 查找 api 文档:

更新:

在我看到这个问题大约一周后,我遇到了一个 XML 解析问题,就像这个问题一样需要 unlazy 函数。您现在可以找到 unlazy in the Tupelo library .

关于xml - Clojure XML 流关闭异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43194162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com