xml - 使用 Clojure zippers 过滤 XML 中的元素节点

标签 xml clojure

如何使用 Clojure zippers 过滤 XML 中的文本节点?例如,您可能有一个打印精美的 XML 文档,该文档将元素节点与包含空格的文本节点交织在一起:

(def doc
  "<?xml version=\"1.0\"?>
  <root>
    <a>1</a>
    <b>2</b>
  </root>")

如果你想获取root的 child 的内容,你可以这样做:

(require '[clojure.data.xml :as xml]
         '[clojure.zip :as zip]
         '[clojure.data.zip :as zf]
         '[clojure.data.zip.xml :as zip-xml])

(-> doc
    xml/parse-str
    zip/xml-zip
    (zip-xml/xml-> :root zf/children zip-xml/text))

但是,这会返回 ("""1""""2"""),包括空格。

如何过滤 zipper ,以便只选择元素节点?

我想到了这个。

(def filter-elements (comp (partial filter (comp xml/element? zip/node)) zf/children))

(-> doc
    xml/parse-str
    zip/xml-zip
    (zip-xml/xml-> :root filter-elements zip-xml/text))
; => ("1" "2")

我怀疑它过于复杂,因此我正在寻找更好的解决方案。

最佳答案

我认为这与决定哪些空格有意义而哪些没有意义的一般 XML 解析问题有关。例如,请参阅此问答:Why am I getting extra text nodes as child nodes of root node?

我检查并发现 data.xml 确实支持通过选项 :skip-whitespace 跳过空格。虽然它没有记录(source)。

所以最好在解析阶段解决这个问题。

(-> doc
    (xml/parse-str :skip-whitespace true)
    zip/xml-zip
    (zip-xml/xml-> :root zf/children zip-xml/text))
; => ("1" "2")

关于xml - 使用 Clojure zippers 过滤 XML 中的元素节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47475799/

相关文章:

java - 实现工具栏调用空对象引用

java - 如何修复错误 :java. lang.IllegalStateException:应为 BEGIN_ARRAY 但在第 1 行第 1 列路径 $ 处为 STRING

clojure - Frege 是否执行尾调用优化?

dictionary - 如何在不知道 Clojure 中的键的情况下将映射分解为键值对?

clojure - 带 Seesaw 的列表框的值

python - 向元素添加注释并使元素文本出现在注释之后

sql-server - SQL Server - 查询缺少命名空间的 XML 列

c# - 在 C# 中创建具有 XML 属性的数组

clojure - 如何在 Clojure 中将列表或向量转换为排序集?

function - 如何在 Clojure 中从字符串定义函数?