diff options
Diffstat (limited to 'src/clojure/contrib/with_pull.clj')
-rw-r--r-- | src/clojure/contrib/with_pull.clj | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/clojure/contrib/with_pull.clj b/src/clojure/contrib/with_pull.clj new file mode 100644 index 00000000..e22b5e56 --- /dev/null +++ b/src/clojure/contrib/with_pull.clj @@ -0,0 +1,46 @@ +(in-ns 'clojure.contrib.lazy-xml) +(import '(org.xmlpull.v1 XmlPullParser XmlPullParserFactory)) + +(defn- attrs [xpp] + (for [i (range (.getAttributeCount xpp))] + [(keyword (.getAttributeName xpp i)) + (.getAttributeValue xpp i)])) + +(defn- ns-decs [xpp] + (let [d (.getDepth xpp)] + (for [i (range (.getNamespaceCount xpp (dec d)) (.getNamespaceCount xpp d))] + (let [prefix (.getNamespacePrefix xpp i)] + [(keyword (str "xmlns" (when prefix (str ":" prefix)))) + (.getNamespaceUri xpp i)])))) + +(defn- attr-hash [xpp] + (into {} (concat (ns-decs xpp) (attrs xpp)))) + +(defn- pull-step [xpp] + (case (.next xpp) + XmlPullParser/START_TAG + (lazy-cons (struct node :start-element + (keyword (.getName xpp)) + (attr-hash xpp)) + (pull-step xpp)) + XmlPullParser/END_TAG + (lazy-cons (struct node :end-element + (keyword (.getName xpp))) + (pull-step xpp)) + XmlPullParser/TEXT + (let [text (.trim (.getText xpp))] + (if (seq text) + (lazy-cons (struct node :characters nil nil text) + (pull-step xpp)) + (recur xpp))))) + +(def #^{:private true} factory + (doto (XmlPullParserFactory/newInstance) + (setNamespaceAware true))) + +(defn- parse-seq-pull [s] + (let [xpp (.newPullParser factory)] + (.setInput xpp s) + (pull-step xpp))) + +(def has-pull true) |