在Python中,我可以使用lxml模块打开XML文件;解析我的数据;查找<DeviceID>, <TamperName>, <SecheduledDateTime>
之类的标签,然后根据其中一个标签的值执行操作。
在Clojure中,我得到了关于如何使用data.xml进行解析的优秀答案,然后通过提取:content标签的val并将信息放在tree-seq中来进一步减少data.xml解析的信息。
然而,即使结果数据嵌入了其他地图标签,显然也不会响应键和val函数。
我可以使用这些数据并使用正则表达式搜索,但我觉得我错过了一些更简单的东西。
data.xml / parse(调用ret-xml-data
)的数据如下所示,在REPL中使用各种(first parsed-xml)和其他命令:
[:tag :TamperExport]
[:attrs {}]
:content
#clojure.data.xml.Element{:tag :Header, :attrs {}, :content
(#clojure.data.xml.Element{:tag :ExportType, :attrs {},
:content ("Tamper Export")}
#clojure.data.xml.Element{:tag :CurrentDateTime,
:attrs {},
:content ("2012-06-26T15:40:22.063")} :attrs {},
:content ("{06643D9B-DCD3-459B-86A6-D21B20A03576}")}
这是我到目前为止的Clojure代码:
(defn ret-xml-data
"Returns a map of the supplied xml file, as parsed by data.xml/parse."
[xml-fnam]
(let [input-xml (try
(java.io.FileInputStream. xml-fnam)
(catch Exception e))]
(if-not (nil? input-xml)
(xmld/parse input-xml)
nil)))
(defn gen-xml-content-tree
"Returns a tree-seq with :content extracted."
[parsed-xml]
(map :content (first (tree-seq :content :content (:content parsed-xml)))))
我想我可能已经找到了一个可重复的数据模式,这样我就可以在不创建大杂烩的情况下解析它:
xml-lib.core=> (first (second cl1))
#clojure.data.xml.Element{:tag :DeviceId, :attrs {}, :content ("80580608")}
xml-lib.core=> (keys (first (second cl1)))
(:tag :attrs :content)
xml-lib.core=> (vals (first (second cl1)))
(:DeviceId {} ("80580608"))
一如既往地感谢你。
编辑: 再添加一些测试。
结果数据,如果我使用像doseq这样的函数运行tree-seq结构,现在可能现在可以通过采取的操作进行解析。
答案 0 :(得分:1)
首先,很难准确说出你想要做什么。在处理编程问题时,它可以帮助您和其他人帮助您拥有一个“小案例”,您可以在向更大的案例工作之前提出并解决。
从听起来,您试图从某些元素中提取内容并根据该内容执行操作。
我整理了一个包含一些简单内容的小型XML文件,以便尝试:
<root>
<someele>
<item1>data</item1>
<deeper>
<item2>else</item2>
</deeper>
</someele>
</root>
我设计它是我认为代表手头问题的一些核心挑战的代表 - 特别是能够在XML中嵌套任意级别的东西。
查看精彩的Clojure Cheatsheet,我找到了xml-seq
,并尝试在clojure.data.xml/parse
d xml上运行它。序列经历了每个元素,然后是子元素,使得迭代XML变得容易。
要选择并使用序列中的特定项目,我喜欢使用for
循环:when
。 :当某些条件成立时,很容易进入循环体。我还使用“set as a function”语义,检查是否有东西在集合中。
(for [ele (xml-seq (load-xml))
:when (#{:item1 :item2} (:tag ele))]
[(:tag ele) (first (:content ele))])
这会返回一系列([:item1“data”] [:item2“else”]),然后可以通过其他方式轻松采取行动。
尝试并牢记Clojure的一个关键事项是,您往往不需要任何特殊的API来执行操作 - 核心语言使您可以轻松地完成大部分工作(如果不是全部的话)。记录(您看到的是返回的内容)也是地图,例如,因此,对它们进行工作,对它们进行处理,以及它们的工作方式。
如果这无法满足您的需求,那么您能提供一个小样本输出和您想要的样本结果吗?
答案 1 :(得分:1)
在(非常)简短的外观之后,我能想到的最接近的Clojure库是Enlive。它被列为HTML模板工具,但我很确定它用于挑选HTML元素的技术也可以应用于XML。