如何使用 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/