# Clojure: Find specific element in HTML tree

I am trying to find all "link" elements that link to RSS feeds in a data structure created by clj-tagsoup. I wrote the following code, which seems to work fine. But: I come from a Java background and I am new to functional programming and clojure, so I am not sure if this is the right way to do it. Could you please give me some hints about what I could improve in the following code:

(defn- matches-attributes [current-attributes required-attributes]
(reduce #(and %1 (= (second %2) ((first %2) current-attributes)))
true
required-attributes))

(defn- find-tag [tag-name current-tag attributes]
(if (= tag-name (tagsoup/tag current-tag))
current-tag
(filter #(and (= tag-name (tagsoup/tag %1))
(matches-attributes (tagsoup/attributes %1) attributes))
(tagsoup/children current-tag))))

(let [document (tagsoup/parse-string (:body page-result))
nil


Edit To clarify a bit, what I am particularily interested in is if traversing the HTML tree the way I do it is the "right" was in a functional language. What I'm also interested in is if "filter" and "reduce" are a good choice as I use them, or if there is a better way. And, of course, I'd also appreciate general hints about what I could do better in this little program...

-

It's not bad, but we can make it a bit more idiomatic. Let's look at this function first:

(defn- matches-attributes [current-attributes required-attributes]
(reduce #(and %1 (= (second %2) ((first %2) current-attributes)))
true
required-attributes))


The use of reduce is a bit odd, instead let's use every? Secondly, if current-attributes is a hash map or a set, then we can actually use it as a function. Since every? takes a predicate, we can rewrite the entire function as:

(defn- matches-attributes [current-attributes required-attributes]
(every? (fn [tv tg]
(= (current-attributes tg) tv))
required-attributes))


On the last function, when-let will help you clean it up a bit more:

(defn- find-rss-feed [page-result]
(let [document (tagsoup/parse-string (:body page-result))

=> (remove #{1 2 3} [1 2 3 4 5 6 7])