Parsed events cannot be emitted
Description
Environment
Clojure 1.7
Activity
Herwig HochleitnerOctober 3, 2016 at 11:37 PM
Sorry, I just stumbled upon this (subscribing the RSS feed now).
My intention for refactoring was not to remove anything, but to make the project more browsable. I tried very hard to not change any functionality, and to finish the refactoring commits before the xmlns work. As you noticed already, all of the original functionality is available in various sub-namespaces and the various record types are not mandatory, but just for efficiency.
In particular, I'd never change anything in clojure.data.xml.tree, as it is an expression of the raw genius of Christophe Grand.
importSeptember 12, 2016 at 3:30 PM
Comment made by: hans
Sure, one example is this package which we use to incrementally construct XML files:
(ns lambdawerk.xml-output
(:require [clojure.data.xml :as xml]
[clojure.data.xml.jvm.emit :as xml.jvm.emit]
[clojure.data.xml.tree :as xml.tree]
[clojure.data.xml.event :as xml.event]))
(def ^:dynamic *writer*)
(defn emit [element]
(doseq [event (xml.tree/flatten-elements [element])]
(xml.jvm.emit/emit-event event *writer*)))
(defmacro with-xml [stream & body]
`(let [^javax.xml.stream.XMLStreamWriter writer# (-> (javax.xml.stream.XMLOutputFactory/newInstance)
(.createXMLStreamWriter ~stream))]
(when (instance? java.io.OutputStreamWriter ~stream)
(xml.jvm.emit/check-stream-encoding ~stream "UTF-8"))
(.writeStartDocument writer# "UTF-8" "1.0")
(let [result# (binding [*writer* writer#] ~@body)]
(.writeEndDocument writer#)
result#)))
(defmacro with-element [element & body]
`(do (xml.jvm.emit/emit-event (xml.event/->StartElementEvent (name ~element) {} nil) *writer*)
(let [result# (do ~@body)]
(xml.jvm.emit/emit-event (xml.event/->EndElementEvent (name ~element)) *writer*)
result#)))
Ryan SeniorSeptember 12, 2016 at 3:10 PM
I think that's an intended use case. Could you attach something that's an example of how you're using it?
importSeptember 12, 2016 at 10:49 AM
Comment made by: hans
Just to follow up: I've found that due to the refactoring of clojure.data.xml into separate packages and the change of event representation to records, it was not apparently obvious how we could continue to use clojure.data.xml the way we did. We've now spent some more time reading the source code and found that the clojure.data.xml.tree, clojure.data.xml.jvm.emit and clojure.data.xml.event packages offer functionality that we require (incremental reading and writing of large XML documents). Can these packages and their exported functionality be considered part of the clojure.data.xml API?
importAugust 29, 2016 at 12:21 PM
Comment made by: hans
Writing that it is "fixed" is a nice way of saying that the functionality has been removed altogether
Events parsed with clojure.data.xml/source-seq cannot be serialized with clojure.data.xml/emit-event because the former puts characters parsed from XML elements into the `:characters` key of the events returned, but the latter expects them to be under the `:chars` key. I would propose that emit-event is changed so that it accepts both `:chars` and `:characters` as key for characters to be serialized, as that will provide the required backwards compatiblity.