在CLojure中如何调用xml->任意的预测

时间:2013-05-24 11:50:01

标签: clojure xml-parsing

我想创建一个允许我从某个Feed中提取内容的函数,这就是我所拥有的... zf来自这里

 (:require
        [clojure.zip :as z] 
        [clojure.data.zip.xml :only (attr text xml->)]
        [clojure.xml :as xml ]
        [clojure.contrib.zip-filter.xml :as zf]
        )

       (def data-url "http://api.eventful.com/rest/events/search?app_key=4H4Vff4PdrTGp3vV&keywords=music&location=Belgrade&date=Future")

     (defn zipp [data] (z/xml-zip data))

    (defn contents[cont & tags] 
      (assert (= (zf/xml-> (zipp(parsing cont)) (seq tags) text))))

但我称之为

(contents data-url :events :event :title)

我收到错误 java.lang.RuntimeException:java.lang.ClassCastException:clojure.lang.ArraySeq无法强制转换为clojure.lang.IFn(NO_SOURCE_FILE:0)

1 个答案:

答案 0 :(得分:4)

(更新以回应评论:请参阅由匹配参数化的现成函数的答案结束。)


以下从问题文本中的URL指向的XML中提取标题(在Clojure 1.5.1 REPL上使用clojure.data.xml 0.0.7和clojure.data.zip 0.1.1进行测试):< / p>

(require '[clojure.zip :as zip]
         '[clojure.data.xml :as xml]
         '[clojure.data.zip.xml :as xz]
         '[clojure.java.io :as io])

(def data-url "http://api.eventful.com/rest/events/search?app_key=4H4Vff4PdrTGp3vV&keywords=music&location=Belgrade&date=Future")
(def data (-> data-url io/reader xml/parse))
(def z (zip/xml-zip data))

(mapcat (comp :content zip/node)
        (xz/xml-> z
                  (xz/tag= :events)
                  (xz/tag= :event)
                  (xz/tag= :title)))

;; value of the above right now:
("Belgrade Early Music Festival, Gosta / Purcell: Dido & Aeneas"
 "Belgrade Early Music Festival, Gosta / Purcell: Dido & Aeneas"
 "Belgrade Early Music Festival, Gosta / Purcell: Dido & Aeneas"
 "VIII Early Music Festival, Belgrade 2013"
 "Kevlar Bikini"
 "U-Recken - Tree of Life Pre event"
 "Green Day"
 "Smallman - Vrane Kamene (Crows Of Stone)"
 "One Direction"
 "One Direction in Serbia")

一些意见:

  1. clojure.contrib.*名称空间全部弃用。 xml->现在住在clojure.data.zip.xml

  2. xml->接受一个zip loc和一堆“谓词”;然而,在这种情况下,“谓词”一词具有在zip locs上工作的过滤功能的不寻常含义。有关返回此类谓词的几个函数,请参阅clojure.data.zip.xml源代码;有关使用的示例,请参见上文。

  3. 如果您想单独定义谓词列表,也可以这样做,然后将xml->apply一起使用:

    (def loc-preds [(xz/tag= :events) (xz/tag= :event) (xz/tag= :title)])
    (mapcat (comp :content zip/node) (apply xz/xml-> z loc-preds))
    ;; value returned as above
    

  4. 更新:这是一个函数,它将url和keywords命名标记作为参数并返回在标记处找到的内容:

    (defn get-content-from-tags [url & tags]
      (mapcat (comp :content zip/node)
              (apply xz/xml->
                     (-> url io/reader xml/parse zip/xml-zip)
                     (for [t tags]
                       (xz/tag= t)))))
    

    这样称呼它:

    (get-content-from-tags data-url :events :event :title)
    

    与上面的mapcat表单给出相同的结果。