August 15, 2019
By: 于壮壮
Clojure XML 转 Json
最近在做微信支付这块,微信接口的都是通过XML来进行数据传输。Clojure中有clojure.data.xml库来让我操作XML格式的数据。 例如:
(require '[clojure.data.xml :as xml])
(def xml-str "<student><name>tom</name><age>18</age></student>")
(xml/parse-str xml-str)
可以看到clojure.data.xml帮我们把繁琐的XML数据格式的转成了一种树形结构。但是依然有冗余的key,像其中的:tag :attrs :content,都增加了我们处理数据的难道。 那可以不可把类似xml的数据格式转成json的数据格式,clojure中对json的处理非常方便的。在网上找到了一篇博客
http://rosario.io/2016/12/26/convert-xml-json-clojure
它是把clojure.data.xml解析的树形结构,通过递归转成json的数据结构,在此基础上我做了一点小改动, 有些细节还有待考虑,不过基本可用。
(require '[clojure.data.xml :as xml])
(defn- same-keys? [content]
(when content
(= 1 (count (distinct (map :tag content))))))
(defn xml->json
"xml转化json"
[element]
(cond
(nil? element) nil
(string? element) element
(map? element) (if-not (empty? element)
{(:tag element) (xml->json (:content element))}
{})
(sequential? element) (cond
(= (count element) 1) (xml->json (first element))
(same-keys? element) (mapv #(xml->json (:content %)) element)
:else (reduce into {} (map #(xml->json %) element)))
:else nil))
(defn xml-str->json
"xml字符串转json"
[xml-str]
(let [element (xml/parse (java.io.StringReader. xml-str))]
(println element)
(xml->json element)))
举几个列子:
(def xml-str "<student><name>tom</name><age>18</age></student>")
(xml-str->json xml-str)
(def xml-str "<student><name>tom</name><age>18</age><numbers><value>1</value><value>2</value></numbers></student>")
(xml-str->json xml-str)
(def xml-str "<student><name>tom</name><age>18</age><products><item><product_id>1</product_id><product_name>西装</product_name></item><item><product_id>1</product_id><product_name>西裤</product_name></item></products></student>")
(xml-str->json xml-str)