Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added code to emit and read cdata

  • Loading branch information...
commit 2815c10b03b905ef2cb5031fdfe37d5bc4fda44b 1 parent 6e695ba
@senior senior authored
View
85 src/main/clojure/clojure/data/xml.clj
@@ -24,12 +24,41 @@
(defn event [type name & [attrs str]]
(Event. type name attrs str))
+(defprotocol Emit
+ (emit-element [element writer]))
+
+(defn write-attributes [{:keys (attrs)} writer]
+ (doseq [[k v] attrs]
+ (.writeAttribute writer (str (namespace k)) (name k) (str v))))
+
; Represents a node of an XML tree
-(defrecord Element [tag attrs content])
+(defrecord Element [tag attrs content]
+ Emit
+ (emit-element [e writer]
+ (let [nspace (namespace (:tag e))
+ qname (name (:tag e))]
+ (.writeStartElement writer "" qname (or nspace ""))
+ (write-attributes e writer)
+ (doseq [c (:content e)]
+ (emit-element c writer))
+ (.writeEndElement writer))))
+
+(defrecord CData [content]
+ Emit
+ (emit-element [e writer]
+ (.writeCData writer (:content e))))
+
+(extend-protocol Emit
+ String
+ (emit-element [e writer]
+ (.writeCharacters writer e)))
(defn element [tag & [attrs & content]]
(Element. tag (or attrs {}) content))
+(defn cdata [content]
+ (CData. content))
+
;=== Parse-related functions ===
(defn- seq-tree
"Takes a seq of events that logically represents
@@ -164,23 +193,25 @@
; protected by a lazy-seq so it's thread-safe.
(defn- pull-seq [^XMLStreamReader sreader]
(lazy-seq
- (loop []
- (condp == (.next sreader)
- XMLStreamConstants/START_ELEMENT
- (cons (event :start-element
- (keyword (.getLocalName sreader))
- (attr-hash sreader) nil)
- (pull-seq sreader))
- XMLStreamConstants/END_ELEMENT
- (cons (event :end-element
- (keyword (.getLocalName sreader)) nil nil)
- (pull-seq sreader))
- XMLStreamConstants/CHARACTERS
- (let [text (.getText sreader)]
- (cons (event :characters nil nil text)
- (pull-seq sreader)))
- XMLStreamConstants/END_DOCUMENT
- nil))))
+ (loop []
+ (condp == (.next sreader)
+ XMLStreamConstants/START_ELEMENT
+ (cons (event :start-element
+ (keyword (.getLocalName sreader))
+ (attr-hash sreader) nil)
+ (pull-seq sreader))
+ XMLStreamConstants/END_ELEMENT
+ (cons (event :end-element
+ (keyword (.getLocalName sreader)) nil nil)
+ (pull-seq sreader))
+ XMLStreamConstants/CHARACTERS
+ (do
+ (let [text (.getText sreader)]
+ (cons (event :characters nil nil text)
+ (pull-seq sreader))))
+
+ XMLStreamConstants/END_DOCUMENT
+ nil))))
(defn lazy-source-seq
"Parses the XML InputSource source using a pull-parser. Returns
@@ -203,24 +234,6 @@
;;;; XML Emitting
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defn write-attributes [{:keys (attrs)} writer]
- (doseq [[k v] attrs]
- (.writeAttribute writer (str (namespace k)) (name k) (str v))))
-
-(defn- emit-element
- "Recursively prints the Element e as XML text."
- [e writer]
-
- (if (instance? String e)
- (.writeCharacters writer e)
- (let [nspace (namespace (:tag e))
- qname (name (:tag e))]
- (.writeStartElement writer "" qname (or nspace ""))
- (write-attributes e writer)
- (doseq [c (:content e)]
- (emit-element c writer))
- (.writeEndElement writer))))
-
(defn emit-stream
"Prints the given Element tree as XML text to *out*. See element-tree.
Options:
View
9 src/test/clojure/clojure/data/xml/test_emit.clj
@@ -10,7 +10,7 @@
:author "Chris Houser"}
clojure.data.xml.test-emit
(:use [clojure.test :only [deftest is are]]
- [clojure.data.xml :as xml :only [element]]
+ [clojure.data.xml :as xml :only [element cdata]]
[clojure.data.xml.test-utils :only (test-stream lazy-parse*)]))
(def deep-tree
@@ -104,3 +104,10 @@
(let [stream (java.io.ByteArrayOutputStream.)]
(binding [*out* (java.io.OutputStreamWriter. stream "UTF-8")]
(xml/emit (element :foo) :encoding "ISO-8859-1"))))))
+
+(deftest emitting-cdata
+ (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<cdata-stuff><![CDATA[<goes><here>]]></cdata-stuff>")
+ (with-out-str
+ (xml/emit (element :cdata-stuff {}
+ (cdata "<goes><here>")))))) )
View
9 src/test/clojure/clojure/data/xml/test_parse.clj
@@ -10,7 +10,7 @@
:author "Chris Houser"}
clojure.data.xml.test-parse
(:use [clojure.test :only [deftest is are]]
- [clojure.data.xml :as xml :only [element]]
+ [clojure.data.xml :as xml :only [element cdata]]
[clojure.data.xml.test-utils :only [test-stream lazy-parse*]]))
(deftest simple
@@ -37,6 +37,13 @@
" t12" (element :g {} "t13") "t14")]
(is (= expected (lazy-parse* input)))))
+(deftest test-cdata-parse
+(let [input "<cdata><is><here><![CDATA[<dont><parse><me>]]></here></is></cdata>"
+ expected (element :cdata {} (element :is {}
+ (element :here {}
+ "<dont><parse><me>")))]
+ (is (= expected (lazy-parse* input)))) )
+
#_(deftest source-seq-release-head
(doseq [func [xml/source-seq xml/lazy-source-seq]]
(let [event1 (atom (xml/event :start-element :foo))
Please sign in to comment.
Something went wrong with that request. Please try again.