在解析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)))
我怎么能意识到原子是否正确解析了?
答案 0 :(得分:1)
for
是懒惰的,在你意识到它产生的序列的元素之前,它不会执行你偷偷摸摸的副作用。你的描述"当我解析原子时,数据是完全写的。"不清楚,但我怀疑你的意思是你在repl中deref它,导致它的值打印,这会强制嵌入其中的懒惰seqs,这会导致它们的副作用运行。
答案 1 :(得分:0)
(vec)
循环之前添加(for)
之后,问题就消失了。
(defn menu->map
"Loops over the xml tree and builds the structure"
[tour-id menu]
(vec ;;forcing the evaluation of the loop
(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]}))))))