我正在尝试使用 clj-xpath 解析一些 xml,基本上我想制作一个看起来像这样的函数
(map
(fn [item]
{:title ($x:text "./title" item)
:url ($x:text "./url" item)})
(take 5
($x "/search/events/event" (xmldoc))))
但是带有任意标签。 到目前为止,我有这个
ns mashup-dsl.datamodel
(:use
[clj-xpath.core])
(def data-url "http://api.eventful.com/rest/events/search? app_key=4H4Vff4PdrTGp3vV&keywords=music&location=Belgrade&date=Future")
(def events-xml
(fn [] (slurp data-url)))
(def xmldoc
(fn [] (xml->doc (events-xml))))
(def item (take 5 ($x "/search/events/event" (xmldoc))))
(defn create-xpath [tag] (str "./" tag))
(def tags ["title" "url"])
(defn parse [item]
(doseq [tag tags])(into {} (keyword tag) ($x:text (create-xpath tag) item)))
但我收到此错误,TransformerException Extra illegal tokens: '$', 'tag', '@', '64516c52' org.apache.xpath.compiler.XPathParser.error (XPathParser.java:610)。所以问题出在解析函数中。有什么想法吗?
最佳答案
以下是提取前 5 个标题的方法:
user=> (map #($x:text "./title" %) (take 5 ($x "//event" (xmldoc))))
("9th International Belgrade Early Music Festival" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\"" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\"" "ICTM Study Group on Music and Dance in Southeastern Europe Conference" "New Belgrade Opera, Madlenianum Opera-Theatre, New Trinity Baroque; Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'incoronazione di Poppea\"")
您的示例 doseq
未正确关闭,您需要编译表达式以针对 xml->doc
结果使用。
您可以创建一个辅助函数,该函数将返回函数以从标签中提取文本:
(defn tag-fn [tag] (partial $x:text tag))
现在,您可以为“title”和“url”生成函数:
user=> (tag-fn "title")
#<core$partial$fn__4190 clojure.core$partial$fn__4190@71cc2b7a>
和
user=> (map (tag-fn "title") (take 5 ($x "//event" (xmldoc))))
("9th International Belgrade Early Music Festival" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\"" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\"" "ICTM Study Group on Music and Dance in Southeastern Europe Conference" "New Belgrade Opera, Madlenianum Opera-Theatre, New Trinity Baroque; Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'incoronazione di Poppea\"")
或网址和标题:
user=> (map (juxt (tag-fn "url") (tag-fn "title")) (take 2 ($x "//event" (xmldoc))))
(["http://eventful.com/belgrade/events/9th-international-belgrade-/E0-001-064654999-7@2014061420?utm_source=apis&utm_medium=apim&utm_campaign=apic" "9th International Belgrade Early Music Festival"] ["http://eventful.com/belgrade/events/belgrade-baroque-academy-mijanovic-gosta-9th-belg-/E0-001-059734872-8?utm_source=apis&utm_medium=apim&utm_campaign=apic" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\""])
或者 url 和 title:
user=> (map (apply juxt (map tag-fn ["url" "title"])) (take 2 ($x "//event" (xmldoc))))
(["http://eventful.com/belgrade/events/9th-international-belgrade-/E0-001-064654999-7@2014061420?utm_source=apis&utm_medium=apim&utm_campaign=apic" "9th International Belgrade Early Music Festival"] ["http://eventful.com/belgrade/events/belgrade-baroque-academy-mijanovic-gosta-9th-belg-/E0-001-059734871-9?utm_source=apis&utm_medium=apim&utm_campaign=apic" "Belgrade Baroque Academy, Mijanovic, Gosta / 9th Belgrade Early Music Festival / Monteverdi: \"L'Incoronazione di Poppea\""])
关于xml - 使用clj-xpath在带有任意标签的clojure中解析xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23920151/