使用Clojure拉链过滤XML中的元素节点 [英] Filter element nodes in XML with Clojure zippers

查看:59
本文介绍了使用Clojure拉链过滤XML中的元素节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can you filter text nodes in XML with Clojure zippers? For example, you may have a pretty-printed XML document that interleaves element nodes with text nodes containing whitespace:

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

如果要检索的孩子的内容,您可以执行以下操作:

If you want to retrieve the content of the root's children, you can do this:

(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),包括空格。

However, this returns (" " "1" " " "2" " "), including the whitespace.

你如何

我想到了这个。

(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")

我怀疑它不必要地复杂,因此我正在寻找更好的解决方案。

I suspect it's unnecessarily complex and hence I'm looking for a better solution.

推荐答案

我认为这与XML解析问题有关,即决定哪个空格有意义,哪个空格没有意义。例如,请参阅以下问题与解答:为什么我会得到额外的文本节点作为根节点的子节点?

I think this relates to the general XML parsing problem of deciding which whitespace is meaningful and which isn’t. See for example this Q&A: Why am I getting extra text nodes as child nodes of root node?

我检查并发现data.xml确实支持通过选项:skip-whitespace 跳过空白。它是未记录的()。

I checked and found that data.xml does support skipping whitespace via an option :skip-whitespace. It’s undocumented though (source).

因此,最好在解析阶段解决此问题。

So best solve this at the parsing stage.

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

这篇关于使用Clojure拉链过滤XML中的元素节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆