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

mac*_*mac 6 xml clojure

下面的往返生成invaild 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
Run Code Online (Sandbox Code Playgroud)

Mic*_*zyk 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;'"/>
Run Code Online (Sandbox Code Playgroud)

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