使用clojure.xml / parse和clojure.xml / emit在Clojure中往返于xml

时间:2010-03-17 14:41:34

标签: xml clojure

下面的往返产生无效的xml,因为结果未正确转义,即属性值包含'而不是'。我做错了还是这个错误?

(ns xml-test
  (:require [clojure.xml :as xml])
  (:require [clojure.zip :as zip]))

(def test-xml "<?xml version="1.0" encoding="UTF-8"?> <main> <item attr='&apos;test&apos;'> </item> </main>")

(def s (ByteArrayInputStream. (.getBytes test-xml "UTF-8")))

(xml/emit (zip/root (zip/xml-zip (clojure.xml/parse s))))

output:

<?xml version='1.0' encoding='UTF-8'?>
<main>
<item attr=''test''/>
</main>
nil

1 个答案:

答案 0 :(得分:8)

我已经快速检查了源代码,clojure.xml/emit-element(由clojure.xml/emit调用)不会将任何字符编码为XML实体。实际上,它允许直接通过属性值。我想这意味着clojure.xml的可用性非常有限;你应该使用clojure.contrib.lazy-xml代替。我很抱歉在你关于XML发射的第一个问题的答案中没有提到它,我没有意识到这样的事情会发生。

使用clojure.contrib.lazy-xml,您可以执行以下操作:

user> (lazy-xml/emit
       (lazy-xml/parse-trim
        (java.io.StringReader. "<foo bar=\"&apos;&quot;&quot;&apos;\"/>")))
<?xml version="1.0" encoding="UTF-8"?><foo bar="'&quot;&quot;'"/>

如果您真的想使用clojure.xml,则必须传递clojure.xml/emit并使用您选择的XML生成器。实际上,您可以使用clojure.xml/parse,对结果进行处理,然后将其传递给clojure.contrib.lazy-xml/emit; XML的Clojure表示结构与两个库相同,但只有后者才能正确发射。