gpt4 book ai didi

xml - 在 Clojure 的 XML 文件中插入 Zipper 树

转载 作者:数据小太阳 更新时间:2023-10-29 01:43:12 24 4
gpt4 key购买 nike

我对如何以惯用方式更改通过 clojure.contrib 的 zip-filter.xml 访问的 xml 树感到困惑。应该尝试这样做,还是有更好的方法?

假设我有一些像这样的虚拟 xml 文件“itemdb.xml”:

<itemlist> 
<item id="1">
<name>John</name>
<desc>Works near here.</desc>
</item>
<item id="2">
<name>Sally</name>
<desc>Owner of pet store.</desc>
</item>
</itemlist>

我有一些代码:

(require '[clojure.zip :as zip]
'[clojure.contrib.duck-streams :as ds]
'[clojure.contrib.lazy-xml :as lxml]
'[clojure.contrib.zip-filter.xml :as zf])

(def db (ref (zip/xml-zip (lxml/parse-trim (java.io.File. "itemdb.xml")))))

;; Test that we can traverse and parse.
(doall (map #(print (format "%10s: %s\n"
(apply str (zf/xml-> % :name zf/text))
(apply str (zf/xml-> % :desc zf/text))))
(zf/xml-> @db :item)))

;; I assume something like this is needed to make the xml tags
(defn create-item [name desc]
{:tag :item
:attrs {:id "3"}
:contents
(list {:tag :name :attrs {} :contents (list name)}
{:tag :desc :attrs {} :contents (list desc)})})

(def fred-item (create-item "Fred" "Green-haired astrophysicist."))

;; This disturbs the structure somehow
(defn append-item [xmldb item]
(zip/insert-right (-> xmldb zip/down zip/rightmost) item))

;; I want to do something more like this
(defn append-item2 [xmldb item]
(zip/insert-right (zip/rightmost (zf/xml-> xmldb :item)) item))

(dosync (alter db append-item2 fred-item))

;; Save this simple xml file with some added stuff.
(ds/spit "appended-itemdb.xml"
(with-out-str (lxml/emit (zip/root @db) :pad true)))

我不清楚在这种情况下如何正确使用 clojure.zip 函数,以及它如何与 zip-filter 交互。

如果您在这个小示例中发现任何特别奇怪的地方,请指出。

最佳答案

首先,您应该在 Fred 的定义中使用 :content(而不是 :contents)。

有了这个改变,下面的方法似乎起作用了:

(-> (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

您的 append-item2 非常相似,只有两处需要更正:

  1. zf/xml-> 返回 zipper 位置序列; zip/rightmost 只接受一个,所以你必须先取出一个(因此是上面的 first);

  2. 完成对 zipper 的修改后,您需要使用 zip/root 返回底层树(的修改版本)。

作为关于样式的最后说明,print + format = printf。 :-)

关于xml - 在 Clojure 的 XML 文件中插入 Zipper 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2872921/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com