pax_global_header00006660000000000000000000000064120731661070014515gustar00rootroot0000000000000052 comment=d344dae465ab17a9440a9cc0ec1fb5b9cebc8562 data.xml-data.xml-0.0.7/000077500000000000000000000000001207316610700147375ustar00rootroot00000000000000data.xml-data.xml-0.0.7/.gitignore000066400000000000000000000000751207316610700167310ustar00rootroot00000000000000/target/ modules/xml/target/ modules/xml.pull-parser/target/ data.xml-data.xml-0.0.7/CHANGES.md000066400000000000000000000005261207316610700163340ustar00rootroot00000000000000From 0.0.6 to 0.0.7 - Fixed bug with args to the indentation function (DXML-7) - Strings now supported as tag names, previously was only kewords (DXML-8) - Add CDATA and comments support to sexp-as-element (DXML-11) - data.xml now properly handles CDATA records that contain an embedded ]]> by breaking it into two CDATA sections (DXML-12)data.xml-data.xml-0.0.7/README.md000066400000000000000000000165311207316610700162240ustar00rootroot00000000000000# data.xml [data.xml](https://github.com/clojure/data.xml) is a Clojure library for reading and writing XML data. This library is the successor to [lazy-xml](http://clojure.github.com/clojure-contrib/lazy-xml-api.html). data.xml has the following features: * Parses XML documents into Clojure data structures * Emits XML from Clojure data structures * No additional dependencies if using 1.6 * Uses StAX internally * lazy - should allow parsing and emitting of large XML documents ## JDK 1.5 This library uses the pull parser that ships with JDK 1.6. If you running on JDK 1.6+, you do not need any additional dependencies. If you are using JDK 1.5, you will need to include a dependency on StAX. More information on this is available [here](https://github.com/clojure/data.xml/blob/jdk16-pull-parser/jdk_15_readme.txt) ## Bugs Please report bugs using JIRA [here](http://dev.clojure.org/jira/browse/DXML). ## Installation Latest stable release: 0.0.6 * [All Released Versions](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22data.xml%22) * [Development Snapshot Versions](https://oss.sonatype.org/index.html#nexus-search;gav~org.clojure~data.xml~~~) ### Maven For Maven projects, add the following XML in your `pom.xml`'s `` section: org.clojure data.xml 0.0.6 ### Leiningen Add the following to the `project.clj` dependencies: [org.clojure/data.xml "0.0.6"] ## Examples The examples below assume you have added a `use` for data.xml: (use 'clojure.data.xml) data.xml supports parsing and emitting XML. The parsing functions will read XML from a [Reader](http://docs.oracle.com/javase/6/docs/api/java/io/Reader.html) or [InputStream](http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html). (let [input-xml (java.io.StringReader. " The baz value")] (parse input-xml)) #clojure.data.xml.Element{:tag :foo, :attrs {}, :content (#clojure.data.xml.Element{:tag :bar, :attrs {}, :content (#clojure.data.xml.Element{:tag :baz, :attrs {}, :content ("The baz value")})})} The data is returned as defrecords and can be manipulated using the normal clojure data structure functions. Additional parsing options can be passed via key pairs: (parse-str "" :coalescing false) #clojure.data.xml.Element{:tag :a, :attrs {}, :content ("\nfoo bar\n" "\nbaz\n")} XML elements can be created using the typical defrecord constructor functions or the element function used below, and written using a [java.io.Writer](http://docs.oracle.com/javase/6/docs/api/java/io/Writer.html).: (let [tags (element :foo {:foo-attr "foo value"} (element :bar {:bar-attr "bar value"} (element :baz {} "The baz value")))] (with-open [out-file (java.io.FileWriter. "/tmp/foo.xml")] (emit tags out-file))) ;;-> Writes XML to /tmp/foo.xml The same can also be expressed using a more Hiccup-like style of defining the elements using sexp-as-element: (= (element :foo {:foo-attr "foo value"} (element :bar {:bar-attr "bar value"} (element :baz {} "The baz value"))) (sexp-as-element [:foo {:foo-attr "foo value"} [:bar {:bar-attr "bar value"} [:baz {} "The baz value"]]])) ;;-> true Comments and CDATA can also be emitted as an S-expression with the special tag names :-cdata and :-comment: (= (element :tag {:attr "value"} (element :body {} (cdata "not parsed true XML can be "round tripped" through the library: (let [tags (element :foo {:foo-attr "foo value"} (element :bar {:bar-attr "bar value"} (element :baz {} "The baz value")))] (with-open [out-file (java.io.FileWriter. "/tmp/foo.xml")] (emit tags out-file)) (with-open [input (java.io.FileInputStream. "/tmp/foo.xml")] (parse input))) #clojure.data.xml.Element{:tag :foo, :attrs {:foo-attr "foo value"}...} There are also some string based functions that are useful for debugging. (let [tags (element :foo {:foo-attr "foo value"} (element :bar {:bar-attr "bar value"} (element :baz {} "The baz value")))] (= tags (parse-str (emit-str tags)))) true Indentation is supported, but should be treated as a debugging feature as it's likely to be pretty slow: (print (indent-str (element :foo {:foo-attr "foo value"} (element :bar {:bar-attr "bar value"} (element :baz {} "The baz value1") (element :baz {} "The baz value2") (element :baz {} "The baz value3"))))) The baz value1 The baz value2 The baz value3 CDATA can be emitted: (emit-str (element :foo {} (cdata ""))) "]]>" But will be read as regular character data: (parse-str (emit-str (element :foo {} (cdata "")))) #clojure.data.xml.Element{:tag :foo, :attrs {}, :content ("")} Comments can also be emitted: (emit-str (element :foo {} (xml-comment "Just a goes here") (element :bar {} "and another element"))) "and another element" But are ignored when read: (emit-str (parse-str (emit-str (element :foo {} (xml-comment "Just a goes here") (element :bar {} "and another element"))))) "and another element" Generated API docs for data.xml are available [here](http://clojure.github.com/data.xml). ## License Licensed under the [Eclipse Public License](http://www.opensource.org/licenses/eclipse-1.0.php). ## Developer Information * [GitHub project](https://github.com/clojure/data.xml) * [Bug Tracker](http://dev.clojure.org/jira/browse/DXML) * [Continuous Integration](http://build.clojure.org/job/data.xml/) * [Compatibility Test Matrix](http://build.clojure.org/job/data.xml-test-matrix/) ## Contributing All contributions need to be made via patches attached to tickets in [JIRA](http://dev.clojure.org/jira/browse/DXML). Check the [Contributing to Clojure](http://clojure.org/contributing) page for more information. data.xml-data.xml-0.0.7/jdk_15_readme.txt000066400000000000000000000011641207316610700200740ustar00rootroot00000000000000data.xml uses the StAX API for parsing XML documents. Projects on JDK 1.6+ will not need any additional dependencies. If you are on JDK 1.5, you will need a StAX implementation. Below is the XML needed to add that dependency to your maven POM: ... stax stax 1.2.0 ... And the Leiningen equivalent: :dependencies [.. [stax "1.2.0"] ...] Note that other StAX implementations should work, but the above will be better tested (and known to work). data.xml-data.xml-0.0.7/pom.xml000066400000000000000000000027301207316610700162560ustar00rootroot00000000000000 4.0.0 data.xml 0.0.7 data.xml jar Functions to parse XML into lazy sequences and lazy trees and emit these as text Chouser chouser@n01se.net http://chouser.n01se.net -5 Alan Malloy amalloy@4clojure.com -8 Ryan Senior senior.ryan@gmail.com -6 org.clojure pom.contrib 0.0.25 scm:git:git@github.com:clojure/data.xml.git scm:git:git@github.com:clojure/data.xml.git git@github.com:clojure/data.xml.git sonatype-oss-snapshots https://oss.sonatype.org/content/repositories/snapshots data.xml-data.xml-0.0.7/src/000077500000000000000000000000001207316610700155265ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/main/000077500000000000000000000000001207316610700164525ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/main/clojure/000077500000000000000000000000001207316610700201155ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/main/clojure/clojure/000077500000000000000000000000001207316610700215605ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/main/clojure/clojure/data/000077500000000000000000000000001207316610700224715ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/main/clojure/clojure/data/xml.clj000066400000000000000000000350211207316610700237640ustar00rootroot00000000000000; Copyright (c) Rich Hickey. All rights reserved. ; The use and distribution terms for this software are covered by the ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) ; which can be found in the file epl-v10.html at the root of this distribution. ; By using this software in any fashion, you are agreeing to be bound by ; the terms of this license. ; You must not remove this notice, or any other, from this software. (ns ^{:doc "Functions to parse XML into lazy sequences and lazy trees and emit these as text." :author "Chris Houser"} clojure.data.xml (:require [clojure.string :as str]) (:import (javax.xml.stream XMLInputFactory XMLStreamReader XMLStreamConstants) (java.nio.charset Charset) (java.io Reader))) ; Represents a parse event. ; type is one of :start-element, :end-element, or :characters (defrecord Event [type name attrs str]) (defn event [type name & [attrs str]] (Event. type name attrs str)) (defn qualified-name [event-name] (if (instance? clojure.lang.Named event-name) [(namespace event-name) (name event-name)] (let [name-parts (str/split event-name #"/" 2)] (if (= 2 (count name-parts)) name-parts [nil (first name-parts)])))) (defn write-attributes [attrs ^javax.xml.stream.XMLStreamWriter writer] (doseq [[k v] attrs] (let [[attr-ns attr-name] (qualified-name k)] (if attr-ns (.writeAttribute writer attr-ns attr-name (str v)) (.writeAttribute writer attr-name (str v)))))) ; Represents a node of an XML tree (defrecord Element [tag attrs content]) (defrecord CData [content]) (defrecord Comment [content]) (defn emit-start-tag [event ^javax.xml.stream.XMLStreamWriter writer] (let [[nspace qname] (qualified-name (:name event))] (.writeStartElement writer "" qname (or nspace "")) (write-attributes (:attrs event) writer))) (defn str-empty? [s] (or (nil? s) (= s ""))) (defn emit-cdata [^String cdata-str writer] (when-not (str-empty? cdata-str) (let [idx (.indexOf cdata-str "]]>")] (if (= idx -1) (.writeCData writer cdata-str ) (do (.writeCData writer (subs cdata-str 0 idx)) (recur (subs cdata-str (+ idx 3)) writer)))))) (defn emit-event [event ^javax.xml.stream.XMLStreamWriter writer] (case (:type event) :start-element (emit-start-tag event writer) :end-element (.writeEndElement writer) :chars (.writeCharacters writer (:str event)) :cdata (emit-cdata (:str event) writer) :comment (.writeComment writer (:str event)))) (defprotocol EventGeneration "Protocol for generating new events based on element type" (gen-event [item] "Function to generate an event for e.") (next-events [item next-items] "Returns the next set of events that should occur after e. next-events are the events that should be generated after this one is complete.")) (extend-protocol EventGeneration Element (gen-event [element] (Event. :start-element (:tag element) (:attrs element) nil)) (next-events [element next-items] (cons (:content element) (cons (Event. :end-element (:tag element) nil nil) next-items))) Event (gen-event [event] event) (next-events [_ next-items] next-items) clojure.lang.Sequential (gen-event [coll] (gen-event (first coll))) (next-events [coll next-items] (if-let [r (seq (rest coll))] (cons (next-events (first coll) r) next-items) (next-events (first coll) next-items))) String (gen-event [s] (Event. :chars nil nil s)) (next-events [_ next-items] next-items) CData (gen-event [cdata] (Event. :cdata nil nil (:content cdata))) (next-events [_ next-items] next-items) Comment (gen-event [comment] (Event. :comment nil nil (:content comment))) (next-events [_ next-items] next-items) nil (gen-event [_] (Event. :chars nil nil "")) (next-events [_ next-items] next-items)) (defn flatten-elements [elements] (when (seq elements) (lazy-seq (let [e (first elements)] (cons (gen-event e) (flatten-elements (next-events e (rest elements)))))))) (defn element [tag & [attrs & content]] (Element. tag (or attrs {}) (remove nil? content))) (defn cdata [content] (CData. content)) (defn xml-comment [content] (Comment. content)) ;=== Parse-related functions === (defn seq-tree "Takes a seq of events that logically represents a tree by each event being one of: enter-sub-tree event, exit-sub-tree event, or node event. Returns a lazy sequence whose first element is a sequence of sub-trees and whose remaining elements are events that are not siblings or descendants of the initial event. The given exit? function must return true for any exit-sub-tree event. parent must be a function of two arguments: the first is an event, the second a sequence of nodes or subtrees that are children of the event. parent must return nil or false if the event is not an enter-sub-tree event. Any other return value will become a sub-tree of the output tree and should normally contain in some way the children passed as the second arg. The node function is called with a single event arg on every event that is neither parent nor exit, and its return value will become a node of the output tree. (seq-tree #(when (= %1 :<) (vector %2)) #{:>} str [1 2 :< 3 :< 4 :> :> 5 :> 6]) ;=> ((\"1\" \"2\" [(\"3\" [(\"4\")])] \"5\") 6)" [parent exit? node coll] (lazy-seq (when-let [[event] (seq coll)] (let [more (rest coll)] (if (exit? event) (cons nil more) (let [tree (seq-tree parent exit? node more)] (if-let [p (parent event (lazy-seq (first tree)))] (let [subtree (seq-tree parent exit? node (lazy-seq (rest tree)))] (cons (cons p (lazy-seq (first subtree))) (lazy-seq (rest subtree)))) (cons (cons (node event) (lazy-seq (first tree))) (lazy-seq (rest tree)))))))))) (defn event-tree "Returns a lazy tree of Element objects for the given seq of Event objects. See source-seq and parse." [events] (ffirst (seq-tree (fn [^Event event contents] (when (= :start-element (.type event)) (Element. (.name event) (.attrs event) contents))) (fn [^Event event] (= :end-element (.type event))) (fn [^Event event] (.str event)) events))) (defprotocol AsElements (as-elements [expr] "Return a seq of elements represented by an expression.")) (defn sexp-element [tag attrs child] (cond (= :-cdata tag) (CData. (first child)) (= :-comment tag) (Comment. (first child)) :else (Element. tag attrs (mapcat as-elements child)))) (extend-protocol AsElements clojure.lang.IPersistentVector (as-elements [v] (let [[tag & [attrs & after-attrs :as content]] v [attrs content] (if (map? attrs) [(into {} (for [[k v] attrs] [k (str v)])) after-attrs] [{} content])] [(sexp-element tag attrs content)])) clojure.lang.ISeq (as-elements [s] (mapcat as-elements s)) clojure.lang.Keyword (as-elements [k] [(Element. k {} ())]) java.lang.String (as-elements [s] [s]) nil (as-elements [_] nil) java.lang.Object (as-elements [o] [(str o)])) (defn sexps-as-fragment "Convert a compact prxml/hiccup-style data structure into the more formal tag/attrs/content format. A seq of elements will be returned, which may not be suitable for immediate use as there is no root element. See also sexp-as-element. The format is [:tag-name attr-map? content*]. Each vector opens a new tag; seqs do not open new tags, and are just used for inserting groups of elements into the parent tag. A bare keyword not in a vector creates an empty element. To provide XML conversion for your own data types, extend the AsElements protocol to them." ([] nil) ([sexp] (as-elements sexp)) ([sexp & sexps] (mapcat as-elements (cons sexp sexps)))) (defn sexp-as-element "Convert a single sexp into an Element" [sexp] (let [[root & more] (sexps-as-fragment sexp)] (when more (throw (IllegalArgumentException. "Cannot have multiple root elements; try creating a fragment instead"))) root)) (defn- attr-prefix [^XMLStreamReader sreader index] (let [p (.getAttributePrefix sreader index)] (when-not (str/blank? p) p))) (defn- attr-hash [^XMLStreamReader sreader] (into {} (for [i (range (.getAttributeCount sreader))] [(keyword (attr-prefix sreader i) (.getAttributeLocalName sreader i)) (.getAttributeValue sreader i)]))) ; Note, sreader is mutable and mutated here in pull-seq, but it's ; protected by a lazy-seq so it's thread-safe. (defn- pull-seq "Creates a seq of events. The XMLStreamConstants/SPACE clause below doesn't seem to be triggered by the JDK StAX parser, but is by others. Leaving in to be more complete." [^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 (if-let [text (and (not (.isWhiteSpace sreader)) (.getText sreader))] (cons (event :characters nil nil text) (pull-seq sreader)) (recur)) XMLStreamConstants/END_DOCUMENT nil (recur);; Consume and ignore comments, spaces, processing instructions etc )))) (def ^{:private true} xml-input-factory-props {:allocator javax.xml.stream.XMLInputFactory/ALLOCATOR :coalescing javax.xml.stream.XMLInputFactory/IS_COALESCING :namespace-aware javax.xml.stream.XMLInputFactory/IS_NAMESPACE_AWARE :replacing-entity-references javax.xml.stream.XMLInputFactory/IS_REPLACING_ENTITY_REFERENCES :supporting-external-entities javax.xml.stream.XMLInputFactory/IS_SUPPORTING_EXTERNAL_ENTITIES :validating javax.xml.stream.XMLInputFactory/IS_VALIDATING :reporter javax.xml.stream.XMLInputFactory/REPORTER :resolver javax.xml.stream.XMLInputFactory/RESOLVER :support-dtd javax.xml.stream.XMLInputFactory/SUPPORT_DTD}) (defn- new-xml-input-factory [props] (let [fac (javax.xml.stream.XMLInputFactory/newInstance)] (doseq [[k v] props :let [prop (xml-input-factory-props k)]] (.setProperty fac prop v)) fac)) (defn source-seq "Parses the XML InputSource source using a pull-parser. Returns a lazy sequence of Event records. Accepts key pairs with XMLInputFactory options, see http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html and xml-input-factory-props for more information. Defaults coalescing true." [s & {:as props}] (let [fac (new-xml-input-factory (merge {:coalescing true} props)) ;; Reflection on following line cannot be eliminated via a ;; type hint, because s is advertised by fn parse to be an ;; InputStream or Reader, and there are different ;; createXMLStreamReader signatures for each of those types. sreader (.createXMLStreamReader fac s)] (pull-seq sreader))) (defn parse "Parses the source, which can be an InputStream or Reader, and returns a lazy tree of Element records. Accepts key pairs with XMLInputFactory options, see http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html and xml-input-factory-props for more information. Defaults coalescing true." [source & props] (event-tree (apply source-seq source props))) (defn parse-str "Parses the passed in string to Clojure data structures. Accepts key pairs with XMLInputFactory options, see http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html and xml-input-factory-props for more information. Defaults coalescing true." [s & props] (let [sr (java.io.StringReader. s)] (apply parse sr props))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; XML Emitting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defn check-stream-encoding [^java.io.OutputStreamWriter stream xml-encoding] (when (not= (Charset/forName xml-encoding) (Charset/forName (.getEncoding stream))) (throw (Exception. (str "Output encoding of stream (" xml-encoding ") doesn't match declaration (" (.getEncoding stream) ")"))))) (defn emit "Prints the given Element tree as XML text to stream. Options: :encoding Character encoding to use" [e ^java.io.Writer stream & {:as opts}] (let [^javax.xml.stream.XMLStreamWriter writer (-> (javax.xml.stream.XMLOutputFactory/newInstance) (.createXMLStreamWriter stream))] (when (instance? java.io.OutputStreamWriter stream) (check-stream-encoding stream (or (:encoding opts) "UTF-8"))) (.writeStartDocument writer (or (:encoding opts) "UTF-8") "1.0") (doseq [event (flatten-elements [e])] (emit-event event writer)) (.writeEndDocument writer) stream)) (defn emit-str "Emits the Element to String and returns it" [e] (let [^java.io.StringWriter sw (java.io.StringWriter.)] (emit e sw) (.toString sw))) (defn ^javax.xml.transform.Transformer indenting-transformer [] (doto (-> (javax.xml.transform.TransformerFactory/newInstance) .newTransformer) (.setOutputProperty (javax.xml.transform.OutputKeys/INDENT) "yes") (.setOutputProperty (javax.xml.transform.OutputKeys/METHOD) "xml") (.setOutputProperty "{http://xml.apache.org/xslt}indent-amount" "2"))) (defn indent "Emits the XML and indents the result. WARNING: this is slow it will emit the XML and read it in again to indent it. Intended for debugging/testing only." [e ^java.io.Writer stream & {:as opts}] (let [sw (java.io.StringWriter.) _ (apply emit e sw (apply concat opts)) source (-> sw .toString java.io.StringReader. javax.xml.transform.stream.StreamSource.) result (javax.xml.transform.stream.StreamResult. stream)] (.transform (indenting-transformer) source result))) (defn indent-str "Emits the XML and indents the result. Writes the results to a String and returns it" [e] (let [^java.io.StringWriter sw (java.io.StringWriter.)] (indent e sw) (.toString sw))) data.xml-data.xml-0.0.7/src/test/000077500000000000000000000000001207316610700165055ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/test/clojure/000077500000000000000000000000001207316610700201505ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/test/clojure/clojure/000077500000000000000000000000001207316610700216135ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/000077500000000000000000000000001207316610700225245ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/xml/000077500000000000000000000000001207316610700233245ustar00rootroot00000000000000data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/xml/test_emit.clj000066400000000000000000000134401207316610700260150ustar00rootroot00000000000000; Copyright (c) Rich Hickey. All rights reserved. ; The use and distribution terms for this software are covered by the ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) ; which can be found in the file epl-v10.html at the root of this distribution. ; By using this software in any fashion, you are agreeing to be bound by ; the terms of this license. ; You must not remove this notice, or any other, from this software. (ns ^{:doc "Tests for emit to print XML text." :author "Chris Houser"} clojure.data.xml.test-emit (:use clojure.test clojure.data.xml [clojure.data.xml.test-utils :only (test-stream lazy-parse*)])) (def deep-tree (lazy-parse* (str "" " t1t2" " t3t4" " t5t6" " t7" " t8t10t11" " t12t13t14" ""))) (deftest defaults (let [expect (str "" "" " t1t2" " t3t4" " t5t6" " t7" " t8t10t11" " t12t13t14" "")] (is (= expect (emit-str deep-tree))))) (deftest defaults ;;XML below should be updated when namespace support is in (let [expect (str "done")] (is (= expect (emit-str (element "foo/bar" {"foo/item" 1} [(element "foo/baz" {"foo/item" 2} "done")])))))) (deftest mixed-quotes (is (= (lazy-parse* (str "" "")) (lazy-parse* (emit-str (element :mixed {:single "'single'quotes'here" :double "\"double\"quotes\"here\""})))))) ;; TODO add an indentation test once we figure out how to indent portably across JREs (defn emit-char-seq [xml-tree encoding] (with-open [bos (java.io.ByteArrayOutputStream.) stream (java.io.OutputStreamWriter. bos encoding)] (emit xml-tree stream :encoding encoding) (.flush stream) (map #(if (pos? %) (char %) %) (.toByteArray bos)))) (deftest encoding (let [input-tree (lazy-parse* "Übercool")] (is (= (concat "" "" [-61 -100] "bercool") (emit-char-seq input-tree "UTF-8"))) (is (= (concat "" "" [-36] "bercool") (emit-char-seq input-tree "ISO-8859-1"))))) (deftest encoding-assertion (is (thrown? Exception (let [stream (java.io.ByteArrayOutputStream.)] (binding [*out* (java.io.OutputStreamWriter. stream "UTF-8")] (emit (element :foo) *out* :encoding "ISO-8859-1")))))) (deftest emitting-cdata (testing "basic cdata" (is (= (str "" "]]>") (emit-str (element :cdata-stuff {} (cdata "")))))) (testing "cdata with ]]> chars" (is (= (str "" "]]>]]>") (emit-str (element :cdata-stuff {} (cdata "]]>")))))) (testing "cdata with ]]> chars and newlines" (is (= (str "" "\n\n\n]]>]]>") (emit-str (element :cdata-stuff {} (cdata "\n\n\n]]>"))))))) (deftest emitting-cdata-with-embedded-end (is (= (str "" "]]>]]>") (emit-str (element :cdata-stuff {} (cdata "]]>"))))) ) (deftest emitting-comment (is (= (str "" "comment not here") (emit-str (element :comment-stuff {} "comment " (xml-comment " goes here ") " not here")))) ) (deftest test-indent (let [nested-xml (lazy-parse* (str "foo")) expect (str "\n\n " "\n \n foo\n \n \n\n") sw (java.io.StringWriter.)] (indent nested-xml sw) (is (= expect (.toString sw))))) (deftest test-indent-str (let [nested-xml (lazy-parse* (str "foo")) expect (str "\n\n " "\n \n foo\n \n \n\n")] (is (= expect (indent-str nested-xml))))) (deftest test-indent (let [nested-xml (lazy-parse* (str "foo")) expect (str "\n\n " "\n \n foo\n \n \n\n") sw (java.io.StringWriter.)] (indent nested-xml sw :encoding "UTF-8") (is (= expect (.toString sw)))))data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/xml/test_parse.clj000066400000000000000000000071471207316610700262000ustar00rootroot00000000000000; Copyright (c) Rich Hickey. All rights reserved. ; The use and distribution terms for this software are covered by the ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) ; which can be found in the file epl-v10.html at the root of this distribution. ; By using this software in any fashion, you are agreeing to be bound by ; the terms of this license. ; You must not remove this notice, or any other, from this software. (ns ^{:doc "Tests for XML parsing functions." :author "Chris Houser"} clojure.data.xml.test-parse (:use clojure.test clojure.data.xml [clojure.data.xml.test-utils :only [test-stream lazy-parse*]])) (deftest simple (let [input "This is bold test" expected (element :html {} (element :body {:bg "red"} "This is " (element :b {} "bold") " test"))] (is (= expected (lazy-parse* input))))) (deftest deep (let [input (str "" " t1t2" " t3t4" " t5t6" " t7" " t8t10t11" " t12t13t14" "") expected (element :a {:h "1", :i "2", :j "3"} " t1" (element :b {:k "4"} "t2") " t3" (element :c {} "t4") " t5" (element :d {} "t6") " t7" (element :e {:l "5" :m "6"} " t8" (element :f {} "t10") "t11") " t12" (element :g {} "t13") "t14")] (is (= expected (lazy-parse* input))) (is (= expected (parse-str input))))) (deftest test-xml-with-whitespace (let [input (str "\n123\n1 2 3\n\n") expected (element :a {} (element :b {:with-attr "s p a c e"} "123") (element :c {} "1 2 3"))] (is (= expected (lazy-parse* input))))) (deftest test-cdata-parse (let [input "]]>" expected (element :cdata {} (element :is {} (element :here {} "")))] (is (= expected (lazy-parse* input))))) (deftest test-comment-parse (let [input "there" expected (element :comment {} (element :is {} (element :here {} "there")))] (is (= expected (lazy-parse* input))))) (deftest test-parsing-processing-instructions (let [input " With Stuff" expected (element :ATag {} "With Stuff")] (is (= expected (parse-str input))))) (deftest test-parsing-doctypes (let [input "

Heading Stuff

" expected (element :html {} (element :h1 {} "Heading Stuff"))] (is (= expected (parse-str input))))) (deftest test-coalescing (let [input ""] (is (= ["\nfoo bar\n\nbaz\n"] (:content (parse-str input)))) (is (= ["\nfoo bar\n" "\nbaz\n"] (:content (parse-str input :coalescing false))))))data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/xml/test_seq_tree.clj000066400000000000000000000042521207316610700266670ustar00rootroot00000000000000; Copyright (c) Rich Hickey. All rights reserved. ; The use and distribution terms for this software are covered by the ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) ; which can be found in the file epl-v10.html at the root of this distribution. ; By using this software in any fashion, you are agreeing to be bound by ; the terms of this license. ; You must not remove this notice, or any other, from this software. (ns ^{:doc "Tests for seq-tree, building a lazy tree from lazy seq." :author "Chris Houser"} clojure.data.xml.test-seq-tree (:use clojure.test clojure.data.xml) (:import (java.lang.ref WeakReference))) (def tt (partial #'seq-tree #(when (= %1 :<) (vector %2)) #{:>} str)) (deftest example (is (= '(("1" "2" [("3" [("4")])] "5") 6) (tt [1 2 :< 3 :< 4 :> :> 5 :> 6])))) (defn limit [& args] (tt (concat args (lazy-seq (throw (Exception. "not lazy enough")))))) (deftest lazy-top-level (is (= '() (take 0 (first (limit 1))))) ; should do better! (is (= '("1") (take 1 (first (limit 1))))) (is (= '("1" "2") (take 2 (first (limit 1 2))))) (is (= '("1" "2" "3") (take 3 (first (limit 1 2 3)))))) (deftest lazy-top-level2 (is (= "1" (reduce nth (limit 1) [0 0]))) (is (= "2" (reduce nth (limit 1 2) [0 1]))) (is (= "3" (reduce nth (limit 1 2 3) [0 2])))) (deftest lazy-child (is (coll? (reduce nth (limit 1 :<) [0 1 0]))) (is (= "2" (reduce nth (limit 1 :< 2) [0 1 0 0]))) (is (= "2" (reduce nth (limit 1 :< 2 :>) [0 1 0 0]))) (is (= "3" (reduce nth (limit 1 :< 2 :> 3) [0 2])))) (deftest lazy-end-of-tree (is (= 3 (count (first (limit 1 :< 2 :> 3 :>))))) (is (= 3 (count (first (limit 1 :< 2 :> 3 :> 4)))))) (deftest release-head-top (let [input (range 10) input-ref (WeakReference. input) output (doall (drop 5 (first (tt input))))] (System/gc) (is (= nil (.get input-ref))) output)) (deftest release-head-nested-late (let [input (list 1 2 :< 3 4 5 :>) input-ref (WeakReference. input) output (doall (drop 2 (first (tt input))))] (System/gc) (is (= nil (.get input-ref))) output)) data.xml-data.xml-0.0.7/src/test/clojure/clojure/data/xml/test_sexp.clj000066400000000000000000000054371207316610700260450ustar00rootroot00000000000000; Copyright (c) Rich Hickey. All rights reserved. ; The use and distribution terms for this software are covered by the ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) ; which can be found in the file epl-v10.html at the root of this distribution. ; By using this software in any fashion, you are agreeing to be bound by ; the terms of this license. ; You must not remove this notice, or any other, from this software. (ns ^{:doc "Tests for reading [:tag {:attr 'value} body*] as XML." :author "Alan Malloy"} clojure.data.xml.test-sexp (:use clojure.test clojure.data.xml [clojure.data.xml.test-utils :only (test-stream lazy-parse*)])) (deftest as-element (let [xml-input "" sexp-input [:tag {:attr "value"} :body]] (is (= (lazy-parse* xml-input) (sexp-as-element sexp-input))))) (deftest as-fragment (let [input (list [:tag1 "stuff"] [:tag2 "other"])] (is (= (sexps-as-fragment input) (map sexp-as-element input))) (is (thrown? Exception (sexp-as-element input))))) (deftest with-cdata (let [xml-input (element :tag {:attr "value"} (element :body {} (cdata "not parsed " (let [xml-input (element :tag {:attr "value"} (element :body {} (cdata "not parsed more not parsed