【发布时间】:2012-06-28 13:43:21
【问题描述】:
对于同一主题的第二个问题,我深表歉意,但我很困惑。是否有遵循 lxml 的 Clojure 模块,甚至是松散的,或者关于如何使用 Clojure 遍历 XML 文件的操作文档?
在 Python 中,我可以使用 lxml 模块打开一个 XML 文件;通过数据解析我的方式;查找<DeviceID>, <TamperName>, <SecheduledDateTime> 之类的标签,然后根据其中一个标签的值执行操作。
在 Clojure 中,我得到了关于如何使用 data.xml 解析然后通过提取 :content 标记的 val 并将信息放入树序列来进一步减少 data.xml 解析的信息的出色答案。
但是,即使结果数据也嵌入了其他地图标签,这些标签显然不会响应键和 vals 函数。
我可以获取这些数据并使用正则表达式搜索,但我觉得我遗漏了一些更简单的东西。
data.xml/parse 中的数据(调用ret-xml-data)看起来像这样,在 REPL 中使用各种(首先解析的 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 的函数遍历树序列结构,结果数据现在可能可以通过所采取的操作进行解析。
【问题讨论】:
-
“嵌入的其他地图标签”到底是什么意思?
-
我无法在文本编辑器中轻松看到树形结构,因此元素看起来是相互嵌入的。基本上,我想要给我时间/日期、endpointid 和任何其他嵌入信息的标签。我通过过滤掉 :content 到达了我想去的地方。这给了我一张更简单的地图。
-
您是否尝试过使用
clojure.pprint/pprint(我想我没记错)。它会自动缩进所有内容。