Create a gist now

Instantly share code, notes, and snippets.

@mnzk /linq.xml.clj
Last active Aug 29, 2015

What would you like to do?
(System.Reflection.Assembly/LoadWithPartialName "System.Xml.Linq")
(ns linq.xml
(:import [System.Xml.Linq XDocument XElement XAttribute XNode])
(:import [System.IO MemoryStream StreamReader])
(:import [System.Text Encoding])
(:gen-class))
(defmacro ^:private local-name [node]
`(.. ~node Name LocalName))
(defprotocol XmlParsable
(parse* [this]))
(extend-protocol XmlParsable
XDocument
(parse* [this] (parse* (.Root this)))
XAttribute
(parse* [this] {(-> this local-name keyword)
(.Value this) })
XElement
(parse* [this]
{:tag (-> this local-name keyword)
:attrs (->> (.Attributes this) (map parse*) (into {}) not-empty)
:content
(let [es (->> (.Elements this) (mapv parse*) not-empty)
v (.Value this)]
(cond
(not (nil? es)) es
(empty? v) nil
:else [v]))})
XNode
(parse* [this] (.Value this)))
;; compatible with clojure.xml/parse
(defn parse [path]
(parse* (XDocument/Load path)))
;; "parse from xml string"
(defn parse-str [s]
(->> s (.GetBytes Encoding/UTF8) (MemoryStream.) (StreamReader.)
XDocument/Load
parse*))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment