xml - 如何在 clojure.data.zip 中使用 xml-> 获取嵌套节点?

标签 xml clojure zipper

我发现 xml-> 的用法非常困惑。我已阅读文档和示例,但无法弄清楚如何获取 xml 文档的嵌套节点。

假设以下 xml 在一个 zipper 中(来自 xml-zip):

<html>
 <body>
  <div class='one'>
    <div class='two'></div>
  </div>
 </body>
</html>

我正在尝试返回带有 class='two' 的 div。

我期待这会起作用:

(xml-> z :html :body :div :div)

或者这个:

(xml-> z :html :body :div (attr= :class "two"))

有点像 css 选择器。

但它只返回第一层,并没有向下搜索树。

我可以让它工作的唯一方法是:

(xml-> z :html :body :div children leftmost?)

这是我应该做的吗?

我开始使用 xml-> 的全部原因是为了方便和避免上下左右导航 zipper 。如果 xml-> 无法获取嵌套节点,那么我看不到 clojure.zip 上的值。

谢谢。

最佳答案

两个连续的 :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"))

关于xml - 如何在 clojure.data.zip 中使用 xml-> 获取嵌套节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44660825/

相关文章:

xml - XPath 'or' 运算符使用 'pipe' 字符?

xml - 为什么 XPath 表达式在 Illustrator 生成的 XML 上失败?

java - xml 的正则表达式不起作用

scala - 在 Scala 中迭代列表的 zipper

clojure - 我如何格式化一棵树以使其与 Clojure 的 zipper 一起使用?

android - Ionic App 的隐私政策

python - 动态语言中的类型类

clojure - 如何在clojure中执行max-by?

performance - Clojure 应用程序启动性能

haskell - Data.Tree.Zipper 中 zipper 数据类型的冗余信息?