Below roundtrip produces invaild xml as the result is not escaped correctly, i.e. the attribute values contain ' instead of apos;. Am I doing somthing wrong or is this a bug?
(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=''test''> </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
I've checked the source quickly and clojure.xml/emit-element
(which gets called by clojure.xml/emit
) makes no effort whatever to encode any characters as XML entities; in fact, it lets attribute values straight through. I guess this means clojure.xml
is quite limited in its usability; you should use clojure.contrib.lazy-xml
instead. My apologies for not mentioning it in the answer to your first question on XML emitting, I didn't realise stuff like this would happen.
With clojure.contrib.lazy-xml
, you can do the following:
user> (lazy-xml/emit
(lazy-xml/parse-trim
(java.io.StringReader. "<foo bar=\"'""'\"/>")))
<?xml version="1.0" encoding="UTF-8"?><foo bar="'""'"/>
If you really wanted to use clojure.xml
, you'd have to pass on clojure.xml/emit
and use an XML producer of your choice instead. Well, actually, you can use clojure.xml/parse
, mangle the result, then pass it to clojure.contrib.lazy-xml/emit
; the structure of the Clojure representation of the XML is the same with both libraries, but only the latter does proper emitting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With