我找到了使用xml->非常混乱。我已经阅读了文档和示例,但无法弄清楚如何获取xml doc的嵌套节点。
假设以下xml在拉链中(从xml-zip开始):
<html>
<body>
<div class='one'>
<div class='two'></div>
</div>
</body>
</html>
我正在尝试使用class =&#39; two&#39;返回div。
我期待这个工作:
(xml-> z :html :body :div :div)
或者这个:
(xml-> z :html :body :div (attr= :class "two"))
有点像css选择器。
但它只返回第一级,并且它不会向下搜索树。
我能让它发挥作用的唯一方法是:
(xml-> z :html :body :div children leftmost?)
这就是我应该做的吗?
我开始使用xml-&gt;的全部原因是为了方便,并避免上下左右拉链拉链。如果是xml->无法获得嵌套节点,然后我看不到clojure.zip上的值。
感谢。
答案 0 :(得分:1)
两个相同的:div
匹配同一个节点。你应该下来。
而且我相信你已经忘记了使用zip/node
获得节点。
(ns reagenttest.sample
(:require
[clojure.zip :as zip]
[clojure.data.zip.xml :as data-zip]))
(let [s "..."
doc (xml/parse (java.io.ByteArrayInputStream. (.getBytes s)))]
(prn (data-zip/xml-> (zip/xml-zip doc) :html :body :div zip/down (data-zip/attr= :class "two") zip/node)))
如果您对xml->
不满意,可以使用自定义抽象:
(defn xml->find [loc & path]
(let [new-path (conj (vec (butlast (interleave path (repeat zip/down)))) zip/node)]
(apply (partial data-zip/xml-> loc) new-path)))
现在你可以这样做:
(xml->find z :html :body :div :div)
(xml->find z :html :body :div (data-zip/attr= :class "two"))
答案 1 :(得分:0)
您可以使用tupelo.forest
from the Tupelo library解决此问题。 forest
包含用于搜索和操作数据树的函数。就像Enlive对类固醇一样。以下是您的数据解决方案:
(dotest
(with-forest (new-forest)
(let [xml-str "<html>
<body>
<div class='one'>
<div class='two'></div>
</div>
</body>
</html>"
enlive-tree (->> xml-str
java.io.StringReader.
en-html/xml-resource
only)
root-hid (add-tree-enlive enlive-tree)
; Removing whitespace nodes is optional; just done to keep things neat
blank-leaf-hid? (fn [hid] (ts/whitespace? (hid->value hid))) ; whitespace pred fn
blank-leaf-hids (keep-if blank-leaf-hid? (all-leaf-hids)) ; find whitespace nodes
>> (apply remove-hid blank-leaf-hids) ; delete whitespace nodes found
; Can search for inner `div` 2 ways
result-1 (find-paths root-hid [:html :body :div :div]) ; explicit path from root
result-2 (find-paths root-hid [:** {:class "two"}]) ; wildcard path that ends in :class "two"
]
(is= result-1 result-2) ; both searches return the same path
(is= (hid->bush root-hid)
[{:tag :html}
[{:tag :body}
[{:class "one", :tag :div}
[{:class "two", :tag :div}]]]])
(is=
(format-paths result-1)
(format-paths result-2)
[[{:tag :html}
[{:tag :body}
[{:class "one", :tag :div}
[{:class "two", :tag :div}]]]]])
(is (val= (hid->elem (last (only result-1)))
{:attrs {:class "two", :tag :div}, :kids []})))))