Insertions into Zipper trees on XML files in Clojure

前端 未结 2 1655
情话喂你
情话喂你 2021-01-04 20:27

I\'m confused as how to idiomatically change a xml tree accessed through clojure.contrib\'s zip-filter.xml. Should be trying to do this at all, or is there a better way?

相关标签:
2条回答
  • 2021-01-04 21:01

    In create-item you mistyped :contents for :content and you should prefer vectors to lists for literals.

    (I was going to make a more comprehensive answer but Michal as already written a pretty good one.)

    An alternative to zip-filter is Enlive:

    (require '[net.cgrand.enlive-html :as e]) ;' <- fix SO colorizer
    
    (def db (ref (-> "itemdb.xml" java.io.File. e/xml-resource))
    
    (defn create-item [name desc]
      {:tag :item
       :attrs {:id "3"}
       :content [{:tag :name :attrs {} :content [name]}
                 {:tag :desc :attrs {} :content [desc]}]})
    
    (def fred-item (create-item "Fred" "Green-haired astrophysicist."))
    
    (dosync (alter db (e/transformation [:itemlist] (e/append fred-item))))
    
    0 讨论(0)
  • 2021-01-04 21:10

    Firstly, you should use :content (and not :contents) in your definition of Fred.

    With that change in place, the following seems to work:

    (-> (zf/xml-> @db :item) ; a convenient way to get to the :item zipper locs
        first                ; but we actually need just one
        zip/rightmost        ; let's move to the rightmost sibling of the first :item
                             ; (which is the last :item in this case)
        (zip/insert-right fred-item) ; insert Fred to the right
        zip/root)            ; get the modified XML map,
                             ; which is the root of the modified zipper
    

    Your append-item2 is very similar, there are just two corrections to make:

    1. zf/xml-> returns a sequence of zipper locs; zip/rightmost accepts just one, so you have to fish one out first (hence the first in the above);

    2. after you're done modifying the zipper, you need to use zip/root to get back at (the modified version of) the underlying tree.

    As a final note on style, print + format = printf. :-)

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