Reputation: 345
I am trying to apply function for extracting content of one tag from xml on a collection of tags. Basically, I am trying to make a function that will extract content from xml, like this
(defn get-events
[xz]
(map (juxt
#(zf/xml1-> % :title zf/text)
#(zf/xml1-> % :performers :performer :name zf/text)
#(zf/xml1-> % :start_time zf/text)
#(zf/xml1-> % :stop_time zf/text))
(zf/xml-> xz :events :event)))
And my solution so far looks like this
(ns datamodel
(:use
[net.cgrand.enlive-html :as en-html ])
(:require
[clojure.zip :as z]
[clojure.xml :as xml ]
[clojure.data.zip.xml :as zf]
[clojure.java.io :as io]
))
(def data-url "http://api.eventful.com/rest/events/search? app_key=4H4Vff4PdrTGp3vV&keywords=music&location=Belgrade&date=Future")
(defn xz [url](z/xml-zip (xml/parse url)))
(defn xml-zipper [& tags](zf/xml-> (xz data-url) tags))
(defn func [& tags]#(zf/xml1-> (xml-zipper tags) % zf/text))
(def tags [:title :venue_name])
and in REPL when I try to apply func to tags like this
(map #((apply comp (reverse( func :events :event))) %) tags)
I get an empty collection ().
Upvotes: 3
Views: 315
Reputation: 9930
When def
ining tags
you are not actually building a literal list but a call to :title
with :venue_name
as its argument. Try declaring tags
as a list or a vector in the following way:
(def tags '(:title :venue_name)) ;list
(def tags [:title :venue_name]) ; vector
I suggest you clean up your code a little bit since there seems to be a number of problems with it:
clojure.data.zip.xml
.xz
.xz
is used as both an alias for a namespace and the name of a function.func
anonymous function (#(zf/xml1-> (xml-zipper tags) % zf/text))
, you are creating and calling that fn
at the same time.Hope it helps.
EDIT
I think I now get what you are trying to do. Here's a working version for the selector generator function: selector
. Note that the argument tag
can be either a single keyword or a sequence of keywords, in which case apply
is used when calling xml1->
.
(ns datamodel
(:require [clojure.zip :as z]
[clojure.xml :as xml]
[clojure.data.zip.xml :as zf]
[clojure.java.io :as io]))
(def data-url "http://api.eventful.com/rest/events/search?app_key=4H4Vff4PdrTGp3vV&keywords=music&location=Belgrade&date=Future")
(defn parse [url]
(z/xml-zip (xml/parse url)))
(defn selector [tag]
(if (sequential? tag)
#(apply zf/xml1-> % (concat tag [zf/text]))
#(zf/xml1-> % tag zf/text)))
(defn get-events
[xml & tags]
(let [events (zf/xml-> xml :events :event)
fs (map selector tags)]
(map (apply juxt fs) events)))
(-> data-url
parse
(get-events :title :start_time [:performers :performer :name] :stop_time)
first
prn)
Upvotes: 3