Skip to content

Commit efdfe97

Browse files
committed
fix round-trip prefix assignments
this cleans up usage of metadata to always store strings into nss-attrs this way, our emitter can restore prefixes and default xmlns, exactly as they appeared in a source
1 parent 5b13e2b commit efdfe97

4 files changed

Lines changed: 18 additions & 11 deletions

File tree

src/main/clojure/clojure/data/xml/jvm/emit.clj

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,15 @@
8282

8383
(defn- compute-pu [pu ns-attrs attr-uris tag-uri tag-local]
8484
(let [tpu (pu/transient pu)
85+
;; add xmlns, if exists
86+
tpu (if-let [uri (get ns-attrs "xmlns")]
87+
(pu/assoc! tpu "" uri)
88+
tpu)
8589
;; add namespaces from current environment
8690
tpu (reduce-kv (fn [tpu ns-attr uri]
91+
(assert (string? ns-attr) (pr-str ns-attr))
8792
(pu/assoc! tpu
88-
(if (str/blank? (qname-uri ns-attr))
89-
(do (assert (= "xmlns" (qname-local ns-attr))
90-
"non-prefixed attribute, that's not xmlns= is not a namespace attr")
91-
"")
92-
(compute-prefix tpu uri (qname-local ns-attr)))
93+
(compute-prefix tpu uri ns-attr)
9394
uri))
9495
tpu ns-attrs)
9596
;; add implicit namespaces used by tag, attrs

src/main/clojure/clojure/data/xml/jvm/parse.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
(reduce (fn [tr ^long i]
5252
(let [ns-pf (.getNamespacePrefix sreader i)]
5353
(assoc! tr (if (str/blank? ns-pf)
54-
:xmlns ns-pf)
54+
"xmlns" ns-pf)
5555
(.getNamespaceURI ^XMLStreamReader sreader i))))
5656
(transient parent-hash)
5757
(range (.getNamespaceCount sreader)))))

src/main/clojure/clojure/data/xml/name.cljc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,10 @@
141141
(defn xmlns-attr?
142142
"Is this qname an xmlns declaration?"
143143
[qn]
144-
(let [uri (qname-uri qn)
145-
local (qname-local qn)]
144+
(let [uri (qname-uri qn)]
146145
(or (= xmlns-uri uri)
147146
(and (str/blank? uri)
148-
(= "xmlns" local)))))
147+
(= "xmlns" (qname-local qn))))))
149148

150149
(defn separate-xmlns
151150
"Call cont with two args: attributes and xmlns attributes"
@@ -157,7 +156,7 @@
157156
(let [val (get attrs qn)]
158157
(if (xmlns-attr? qn)
159158
(recur attrs*
160-
(assoc! xmlns* qn val)
159+
(assoc! xmlns* (qname-local qn) val)
161160
(next attrs'))
162161
(recur (assoc! attrs* qn val)
163162
xmlns*

src/test/clojure/clojure/data/xml/test_emit.clj

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,17 @@
221221

222222
(deftest test-default-xmlns
223223
(let [nss-meta (comp :clojure.data.xml/nss meta)]
224-
(is (= {:xmlns "NS"}
224+
(is (= {"xmlns" "NS"}
225225
(nss-meta (parse-str "<foo xmlns=\"NS\"/>"))
226226
(nss-meta (parse-str (emit-str (parse-str "<foo xmlns=\"NS\"/>"))))))))
227227

228228
(deftest test-empty-elements
229229
(is (= (emit-str {:tag :a :content []}) "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a/>"))
230230
(is (= (emit-str {:tag :a :content [""]}) "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a></a>")))
231+
232+
(deftest test-roundtrip
233+
(is (= (emit-str (with-meta (parse-str "<foo:element xmlns:foo=\"FOO:\"/>")
234+
nil))
235+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><a:element xmlns:a=\"FOO:\"/>"))
236+
(is (= (emit-str (parse-str "<foo:element xmlns:foo=\"FOO:\"/>"))
237+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><foo:element xmlns:foo=\"FOO:\"/>")))

0 commit comments

Comments
 (0)