【发布时间】:2017-06-07 16:10:25
【问题描述】:
在解析 xml 文件时,我将值标准化并通过交换保存它们!变成一个原子。另外我建了一棵树来反映原始结构。
当我调用该函数时,它只返回一部分数据,而不是标准化值。当我取消引用原子时,数据已完全写入。
这里是代码的一部分,这似乎对该行为至关重要。
(defn normalize-values
"Save the dataset to the atom and returns the reference"
[tour-id key value]
(swap! db assoc-in [tour-id (query-key key :name) value] {:title value})
{key [(query-key key) value]})
(defn extract-tags
"Differs between unique and normalizable values"
[node tour-id]
(let [data (zip/xml-zip node)
key (:tag node)
value (zx/xml1-> data key zx/text)
res (if (some #{key} [:sound :map :video :creator])
(normalize-values tour-id key value)
{key value})]
res))
(defn panorama->map
"Creates a panorama map from the xml data"
[node tour-id]
(let [xml-node (zip/node node)
tag-values (into {} (map #(extract-tags % tour-id) (:content xml-node)))]
(merge tag-values
{:id (get-file-id (:file tag-values))
:hidden (read-string (get-in xml-node [:attrs :hidden]))})))
(defn menu->map
"Loops over the xml tree and builds the structure"
[tour-id menu]
(for [entry menu]
(let [children (childs-of-child entry)]
(if (not-empty children)
(let [{:keys [id] :as category-map} (category->map entry)]
(swap! db assoc-in [tour-id (query-key :categorie :id) id] category-map)
{:loc [:categories/by-id id]
:children (menu->map tour-id children)})
(let [{:keys [id] :as panorama-map} (panorama->map entry tour-id)]
(swap! db assoc-in [tour-id (query-key :pano :id) id] panorama-map)
{:loc [:panos/by-id id]})))))
(defn parse-menu
"Starting function which resets the db and saves all data to the atom "
[path id]
(swap! db dissoc id)
(logging/debug "Parse Menu: " path)
(let [xml (xml->map path)
menu-data (menu->map id (:content xml))]
(swap! db assoc-in [id :title] (tour-title xml))
(swap! db assoc-in [id :tree] menu-data)
(get @db id)))
我怎样才能意识到原子被正确解析了?
【问题讨论】:
-
您能否更清楚地了解究竟哪里出了问题,以及您在调试时看到了什么?另外,能发一下
xml->map的出处吗? -
我建议始终使用构造
(vec (for ...))在除极少数情况外的所有情况下禁用惰性结果。在 Tupelo 库中,我为此目的定义了forv(类似于 clojure.core 中的mapv)。 -
谢谢,vec 的提示带来了解决方案。我忘了,那个 for 也很懒。
标签: xml clojure lazy-evaluation