parsing XML in clojure

前端 未结 1 1248
自闭症患者
自闭症患者 2020-12-29 17:52

I am new to clojure so please bear with me. I have a XML which looks like this




        
相关标签:
1条回答
  • 2020-12-29 18:20

    I would use data.zip (Formerly clojure.contrib.zip-filter). It provides a lot of xml-parsing power and it's easily capable of performing xpath like expressions. The README describes it as a System for filtering trees, and XML trees in particular.

    Below I have some sample code for creating a "row" for the CSV file. The row is a map of the column name to the attribute value.

    (ns work 
        (:require [clojure.xml :as xml]
                  [clojure.zip :as zip]
                  [clojure.contrib.zip-filter.xml :as zf]))
    
    ; create a zip from the xml file
    (def zip (zip/xml-zip (xml/parse "data.xml")))
    
    ; pulls out a list of all of the root "Id" attribute values
    (zf/xml-> zip (zf/attr :Id))
    
    (defn value [xvar-zip]
      "Finds the id and value for a particular element"
      (let [id (-> xvar-zip zip/node :attrs :Id) ; manual access
            value (zf/xml1-> xvar-zip ; use xpath like expression to pull value out
                             :Row ; need the row element
                             :Col ; then the column element
                             (zf/attr :Value))] ; and finally pull the Value out
        {id value}))
    
    ; gets the "column-value" pair for a single column
    (zf/xml1-> zip
               (zf/attr= :Id "cdx9") ; filter on id "cdx9" 
               :XVar ; filter on XVars under it 
               (zf/attr= :Id "TrancheAnalysis.IndexDuration") ; filter on id
               value) ; apply the value function on the result of above
    
    ; creates a map of every column key to it's corresponding value
    (apply merge (zf/xml-> zip (zf/attr= :Id "cdx9") :XVar value))
    

    I'm not sure how the xml would work with multiple Dictionary XVars, as it is a root element. If you need to, one of the other functions which is useful for this type of work is mapcat, which cats all of the values returned from the mapping function.

    There are some more examples in the test source as well.

    One other big recommendation I have is to make sure you use a lot of small functions. You'll find things much easier to debug, test, and work with.

    0 讨论(0)
提交回复
热议问题