Clojure XML 解析

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1194044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 12:39:35  来源:igfitidea点击:

Clojure XML Parsing

xmlclojureclojure-contrib

提问by Hamza Yerlikaya

I can not find any info on how to parse xml documents and access elements.

我找不到有关如何解析 xml 文档和访问元素的任何信息。

I have found two ways to parse the xml document

我找到了两种解析xml文档的方法

(clojure.zip/xml-zip (clojure.xml/parse file))

and

(parse-seq file)

but i can seem to find any info on how to process the resulting structure?

但我似乎可以找到有关如何处理结果结构的任何信息?

Source file's refers to zip-query.clj on how to query the result but that seems to missing too.

源文件是指关于如何查询结果的 zip-query.clj,但这似乎也缺失了。

回答by Pinochle

Suppose you have the following xml to parse in your file:

假设您的文件中有以下 xml 需要解析:

<high-node>
   <low-node>my text</low-node>
</high-node>

you load clojure.xml:

你加载clojure.xml

user=> (use 'clojure.xml)

when parsed, the xml will have the following structure:

解析后,xml 将具有以下结构:

{:tag :high-node, :attrs nil, :content [{:tag :low-node, :attrs nil, :content ["my text"]}]}

and then you can seq over the content of the file to get the content of the low-node:

然后您可以对文件的内容进行 seq 以获取以下内容low-node

user=> (for [x (xml-seq 
              (parse (java.io.File. file)))
                 :when (= :low-node (:tag x))]
         (first (:content x)))

("my text")

Similarly, if you wanted to have access to the entire list of information on low-node, you would change the :whenpredicate to (= (:high-node (:tag x))):

同样,如果您想访问低节点上的整个信息列表,您可以将:when谓词更改为(= (:high-node (:tag x)))

user=> (for [x (xml-seq 
              (parse (java.io.File. file)))
                 :when (= :high-node (:tag x))]
         (first (:content x)))

({:tag :low-node, :attrs nil, :content ["my text"]})

This works because the keywords can operate as functions. See Questions about lists and other stuff in Clojureand Data Structures: Keywords

这是有效的,因为关键字可以作为函数运行。请参阅有关 Clojure数据结构中的列表和其他内容的问题:关键字

回答by overthink

The above answer works, but I find it a lot easier to use clojure.data.zip.xml(used to be clojure-contrib.zip-filter.xmlprior to Clojure 1.3).

上面的答案有效,但我发现它更容易使用clojure.data.zip.xml(曾经clojure-contrib.zip-filter.xml在 Clojure 1.3 之前)。

file:

文件:

myfile.xml:

myfile.xml

<songs>
  <track id="t1"><name>Track one</name></track>
  <track id="t2"><name>Track two</name></track>
</songs>

code:

代码:

; Clojure 1.3
(ns example
  (:use [clojure.data.zip.xml :only (attr text xml->)]) ; dep: see below
  (:require [clojure.xml :as xml]
            [clojure.zip :as zip]))

(def xml (xml/parse "myfile.xml"))
(def zipped (zip/xml-zip xml))
(xml-> zipped :track :name text)       ; ("Track one" "Track two")
(xml-> zipped :track (attr :id))       ; ("t1" "t2")

Unfortunately, you need to pull in a dependency on data.zipto get this nice read/filter functionality. It's worth the dependency :)In leinit would be (as of 17-Aug-2013):

不幸的是,您需要依赖于data.zip才能获得这个不错的读取/过滤功能。 值得依赖:)lein中(截至 2013 年 8 月 17 日):

[org.clojure/data.zip "0.1.1"]

And as for docs for data.zip.xml... I just look at the relatively small source file hereto see what is possible. Another good SO answer here, too.

至于文档data.zip.xml...我只是看看这里相对较小的源文件,看看有什么可能。这里也是另一个很好的 SO 答案。