本節書摘來自華章社群《clojure資料分析秘笈》一書中的第1章,第1.7節将xml資料讀入incanter資料集,作者(美)eric rochester,更多章節内容可以通路雲栖社群“華章社群”公衆号檢視
1.7 将xml資料讀入incanter資料集
一類非常常用的資料格式是xml,人們對其褒貶不一。但在某種情況下,幾乎所有人都不得不處理它。clojure可以使用java的xml庫,但它也有自己的包,這個包提供了一種在clojure中使用xml的更自然的方式。
1.7.1 準備工作
首先,在leiningen project.clj檔案中引入以下依賴:

1.7.3 實作原理
本方法按以下順序處理xml:
解析xml資料檔案。
利用解析樹抽取資料節點。
将節點轉換成代表資料的映射序列。
最後,将其轉換至incanter資料集。
load-xml-data實作了這個過程。其中包括三個參數:輸入檔案名、傳入解析完成的xml的根節點并傳回第一個資料節點的函數,以及傳入一個資料節點并傳回下個資料節點或空值(如果其後沒有節點)的函數。
首先,函數解析xml檔案并将之裝入zipper(将在後面的章節詳細讨論zipper),然後利用傳入的兩個函數将資料節點抽取成一個序列。對于每個資料節點,擷取其子節點并将其轉換成一系列“标簽名/内容”對。每個資料節點的對轉換成一個映射,然後映射序列轉換至incanter資料集。
1.7.4 更多資訊
本方法中使用了一對有趣的資料結構或概念。這兩種資料結構在函數式程式設計語言或者lisp中都很常見,但是都未出現在主流的程式設計語言中,接下來深入學習一下。
利用zipper浏覽結構
解析完成後的xml檔案需要作為參數傳入clojure.zip/xml-zip。這将使用clojure本身的xml資料結構并将其轉換成可以用如clojure.zip/down和clojure.zip/right之類的指令進行快速浏覽。作為一門函數式程式設計語言,clojure使用不可變資料結構;而zipper提供了一種浏覽、修改類樹結構的高效、自然方法,例如xml文檔。
流水線處理
可以使用->>宏來以流水線的方式展示處理過程。對于深度嵌套的函數調用,這個宏需要從右往左閱讀,這使得處理過程的資料流和轉換序列更清晰。
在clojure中可以執行流水線處理是因為它的宏系統。->>僅将函數調用重寫成clojure本身的嵌套的格式,與格式讀入的方式一樣。傳入宏的第一個參數将作為下一個表達式的最後一個參數插入。資料結構則插入第三個表達式作為最後一個參數,等等,直到這種格式結束。也就是說,以(->> x first (map length) (apply +))表達式開始。接下來是clojure建構最終表達式的一系列中間步驟(需要整合的元素在每個階段都會高亮顯示)。
(->> x first (map length) (apply +))
(->> (first x) (map length) (apply +))
(->> (map length (first x)) (apply +))
(apply + (map length (first x)))
比較xml和json
xml和json(在1.4節中提到)非常相似。可以證明的是,json的流行很大程度上是被對xml冗長特性的醒悟所驅動的。
當在clojure中處理這些格式的資料時,最大的不同在于json資料是直接轉換成對應資料内容的clojure内部資料結構,例如映射和向量。然而對于xml而言,xml被讀入至反映xml結構的記錄類型,而不是反映資料結構的記錄類型。
換句話說,json中的映射的鍵值來自域,例如,來自first_name或者age。然而,xml中映射的鍵值來自資料格式、标簽、屬性或者子節點,也就是說,标簽和屬性名來自域。這額外的一層抽象使得xml更加不靈活。