Clojure模块是否相当于Python的lxml?

时间:2012-06-28 13:43:21

标签: clojure lxml

我为同一主题的第二个问题道歉,但我很困惑。是否有一个遵循lxml的Clojure模块,甚至是松散的,或者如何使用Clojure如何遍历XML文件的方法文档?

在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结构,现在可能现在可以通过采取的操作进行解析。

2 个答案:

答案 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。