如何优雅地解析 clojure 中的 xml

mat*_*ter 1 clojure

我有一段从 XML 构建句子的代码,如下所示。我想知道什么可能是替代代码,在被黑客入侵后会更具可读性。

     (mapcat
        (fn [el]
           (map special-join
              (map
                  (fn [el] (map zip-xml/text (zip-xml/xml-> el :word)))
                  (zip-xml/xml-> el :sentence))))
        (zip-xml/xml-> root :document))
Run Code Online (Sandbox Code Playgroud)

考虑到重复内联函数定义与嵌套探测相结合,上面的代码不是很易读,但是像在这个官方教程中那样将它们分解成独立的函数对于这种简单的情况对我来说真的没有意义。

为了完整起见,这是解析的重复 XML 结构

<document>
  <sentence id="1">
    <word id="1.1">Foo</w>
    <word id="1.2">bar</w>
  </sentence>
</document>
Run Code Online (Sandbox Code Playgroud)

exu*_*ero 5

在这种情况下,拉链可能有点矫枉过正。clojure.xml/parse将为您提供一个表示 HTML 的简单数据结构。

(require '[clojure.xml :as xml] '[clojure.string :as string])

(def doc
  (->
"<document>
  <sentence id=\"1\">
    <word id=\"1.1\">
      Foo
    </word>
    <word id=\"1.2\">
      bar
    </word>
  </sentence>
</document>
" .getBytes java.io.ByteArrayInputStream. xml/parse))
Run Code Online (Sandbox Code Playgroud)

然后您可以使用xml-seq获取所有<sentence>标签及其子项,收集子项的文本内容,修剪空格并加入空格。

(->> doc
  xml-seq
  (filter (comp #{:sentence} :tag))
  (map :content)
  (map #(transduce
          (comp
            (mapcat :content)
            (map string/trim)
            (interpose " "))
          str %)))
Run Code Online (Sandbox Code Playgroud)