Remove specific XML nodes using Clojure

后端 未结 3 646
悲&欢浪女
悲&欢浪女 2021-01-24 07:45

I have the following XML structure:

(def xmlstr
\"
  
    AAA         


        
3条回答
  •  忘了有多久
    2021-01-24 08:22

    The Clojure standard APIs provide convenient functions for manipulating XML and other tree structures. Removing (leaf) nodes can be done on depth-first traversal using clojure.walk:

    (require '[clojure.xml :as xml]
             '[clojure.walk :as walk])
    
    (def xmlstr
    "
      
        AAA
        BBB
        CCC
        AAA
      
    ")
    
    (def xmldoc (xml/parse (java.io.ByteArrayInputStream. (.getBytes xmlstr))))
    
    (defn tag-matches [item tag]
      (= (:tag item) tag))
    
    (defn content-matches [item to-match]
      ((into #{} to-match)
       (apply str (:content item))))
    
    (defn match-criteria [item to-match]
      (some #(and (tag-matches % :Type)
                  (content-matches % to-match))
            (:content item)))
    
    (defn mk-xml-walker [& to-remove]
      (fn [form]
        (if (and (vector? form)
                 (some #(tag-matches % :Item) form))
          (filter (complement #(match-criteria % to-remove)) form)
          form)))
    
    (xml/emit (walk/postwalk (mk-xml-walker "B" "C") xmldoc))
    

    For magical one-liners, you may also want to check out Specter which provides a very concise syntax for manipulating nested data structures, like XML.

提交回复
热议问题