2012-06-28 69 views
3

我對同一主題的第二個問題表示歉意,但我很困惑。是否有一個遵循lxml的Clojure模塊,甚至是鬆散的,或者如何使用Clojure瀏覽XML文件?Clojure模塊是否等價於Python的lxml?

在Python中,我可以使用lxml模塊打開XML文件;通過數據解析我的方式;尋找像<DeviceID>, <TamperName>, <SecheduledDateTime>這樣的標籤,然後根據其中一個標籤的值執行操作。

在Clojure中,我已經給出瞭如何使用data.xml進行解析的優秀答案,然後通過提取:content標記的val並將信息放入樹狀seq來進一步減少data.xml解析的信息。

但是,即使是由此產生的數據也嵌入了其他地圖標記,這顯然不會響應鍵和vals函數。

我可以採取這些數據並使用正則表達式搜索,但我覺得我錯過了更簡單的事情。

數據右出data.xml中/解析的(呼叫ret-xml-data)看起來像這樣,使用各種(首先被解析的XML)和其他命令在REPL:

[:tag :TamperExport] 
[:attrs {}] 
:content 
#clojure.data.xml.Element{:tag :Header, :attrs {}, :content 
(#clojure.data.xml.Element{:tag :ExportType, :attrs {}, 
:content ("Tamper Export")} 
#clojure.data.xml.Element{:tag :CurrentDateTime, 
:attrs {}, 
:content ("2012-06-26T15:40:22.063")} :attrs {}, 
:content ("{06643D9B-DCD3-459B-86A6-D21B20A03576}")} 

這裏是Clojure的代碼我到目前爲止有:

(defn ret-xml-data 
    "Returns a map of the supplied xml file, as parsed by data.xml/parse." 
    [xml-fnam] 

    (let [input-xml (try 
         (java.io.FileInputStream. xml-fnam) 
         (catch Exception e))] 

     (if-not (nil? input-xml) 
      (xmld/parse input-xml) 
      nil))) 

(defn gen-xml-content-tree 
    "Returns a tree-seq with :content extracted." 

    [parsed-xml] 
    (map :content (first (tree-seq :content :content (:content parsed-xml))))) 

我想我可能已經找到了一個可重複的圖案,讓我來分析這個不創建一個大雜燴的數據:

xml-lib.core=> (first (second cl1)) 
#clojure.data.xml.Element{:tag :DeviceId, :attrs {}, :content ("80580608")} 
xml-lib.core=> (keys (first (second cl1))) 
(:tag :attrs :content) 
xml-lib.core=> (vals (first (second cl1))) 
(:DeviceId {} ("80580608")) 

謝謝你一如既往。

編輯: 添加一些更多的測試。

如果我使用像doseq這樣的函數來遍歷tree-seq結構,可能現在可以通過採取的操作來解析結果數據。

+0

「嵌入的其他地圖標記」究竟是什麼意思? – deterb

+0

我無法在文本編輯器中輕鬆查看樹結構,因此元素顯示爲彼此嵌入。基本上,我想要的標籤給我時間/日期,endpointid,和任何其他信息嵌入。我通過過濾出來了我想要的東西:內容。這給了我一個更簡單的地圖。 – octopusgrabbus

+0

你有沒有嘗試過使用'clojure.pprint/pprint'(我想我記得那是正確的)。它會自動縮進一切。 – deterb

回答

1

首先,很難確切地告訴你想要做什麼。在處理編程問題時,它可以幫助您和其他人幫助您在面對更大問題之前提供並解決「小問題」。

從聽起來像,你試圖拉出某些元素的內容,並根據該內容執行操作。

我把一個小的XML文件,一些簡單的內容嘗試的東西出來:

<root> 
    <someele> 
     <item1>data</item1> 
     <deeper> 
      <item2>else</item2> 
     </deeper> 
    </someele> 
</root> 

我設計它是什麼,我認爲是有代表性的一些有問題的核心挑戰在眼前 - 特別是能夠在XML中嵌套任意級別的東西。

看着美好的Clojure Cheatsheet,我發現xml-seq,並試圖在clojure.data.xml/parse d xml上運行它。序列遍歷每個元素,然後遍歷它們的子元素,從而可以輕鬆遍歷XML。

要挑選和處理序列中的特定項目,我喜歡使用for環路與:when。 :當某些條件成立時,可以很容易地進入循環體。我還利用「作爲函數設置」語義,它檢查是否在集合中有東西。

(for [ele (xml-seq (load-xml)) 
     :when (#{:item1 :item2} (:tag ele))] 
    [(:tag ele) (first (:content ele))]) 

這回來的序列([:項目1「數據」] [:ITEM2「其他」]),其可以很容易在其他方面採取行動。

關於Clojure的一個關鍵嘗試和記住的事情是,你傾向於不需要任何特殊的API來做東西 - 核心語言可以很容易地完成大部分(如果不是全部)你需要做的事情。記錄(也就是你看到的返回的)也是地圖,所以assoc,dissoc等等對它們起作用,並且它們是如何處理它們的。

如果這不能幫助您達到您的需要,那麼您可以提供一個小樣本輸出和樣本結果嗎?

1

我認爲最接近的Clojure庫在lxml(非常)簡短的外觀後稱爲Enlive。它被列爲HTML模板工具,但我很確定它用於挑選HTML元素的技術也可以應用於XML。

+0

謝謝。我會看看。 – octopusgrabbus

相關問題