Clojure XML Parsing



  • 3 Answer(s)

    XML to parse in the file:

    <high-node>
      <low-node>my text</low-node>
    </high-node>
    

         load clojure.xml:

    user=> (use 'clojure.xml)
    

         while it is parsed, then the xml will have the structure like,

    {:tag :high-node, :attrs nil, :content [{:tag :low-node, :attrs nil, :content ["my text"]}]}
    

         then we can seq over the content of the file to get the content of the low-node:

    user=> (for [x (xml-seq
                  (parse (java.io.File. file)))
                       :when (= :low-node (:tag x))]
              (first (:content x)))
     
    ("my text")
    

         Normally, if we need to have access to the whole list of information on low-node, we can change the :when predicate to (= (:high-node (:tag x))):

    user=> (for [x (xml-seq
                  (parse (java.io.File. file)))
                        :when (= :high-node (:tag x))]
              (first (:content x)))
     
    ({:tag :low-node, :attrs nil, :content ["my text"]})
    
    Answered on January 12, 2019.
    Add Comment

         Use clojure.data.zip.xml which is used to be clojure-contrib.zip-filter.xml prior to Clojure 1.3.

    file: myfile.xml

    <songs>
      <track id="t1"><name>Track one</name></track>
      <track id="t2"><name>Track two</name></track>
    </songs>
    

    code:

    ; Clojure 1.3
    (ns example
      (:use [clojure.data.zip.xml :only (attr text xml->)]) ; dep: see below
      (:require [clojure.xml :as xml]
              [clojure.zip :as zip]))
     
    (def xml (xml/parse "myfile.xml"))
    (def zipped (zip/xml-zip xml))
    (xml-> zipped :track :name text)     ; ("Track one" "Track two")
    (xml-> zipped :track (attr :id))     ; ("t1" "t2")
    

         The user want to pull in a dependency on data.zip to get this nice read/filter functionality by unfortunate.

    [org.clojure/data.zip "0.1.1"]
    

         Then for docs for data.zip.xml. The relative small source file here to see what is possible.

    Answered on January 12, 2019.
    Add Comment
    (require '[clojure.xml :as xml]
             '[clojure.zip :as zip])
    
    ;;convenience function, first seen at nakkaya.com later in clj.zip src
    (defn zip-str [s]
      (zip/xml-zip 
          (xml/parse (java.io.ByteArrayInputStream. (.getBytes s)))))
    
    ;;parse from xml-strings to internal xml representation
    user=> (zip-str "<a href='nakkaya.com'/>")
    [{:tag :a, :attrs {:href "nakkaya.com"}, :content nil} nil]
    
    ;;root can be rendered with xml/emit-element
    user=> (xml/emit-element (zip/root [{:tag :a, :attrs {:href "nakkaya.com"}, :content nil} nil]))
    <a href='nakkaya.com'/>
    
    ;;printed (to assure it's not lazy and for performance), can be caught to string variable with with-out-str

     

    Answered 7 days ago.
    Add Comment


  • Your Answer

    By posting your answer, you agree to the privacy policy and terms of service.