2010-05-07 14 views
8

Digamos que estoy analizando un canal RSS y quiero extraer un subconjunto de información del mismo.Forma idiomática de crear una estructura personalizada a partir de una cremallera XML en Clojure

(def feed (-> "http://..." clojure.zip/xml-zip clojure.xml/parse)) 

puedo conseguir enlaces y títulos por separado:

(xml-> feed :channel :item :link text) 
(xml-> feed :channel :item :title text) 

Sin embargo no puedo averiguar la manera de extraer de ellos al mismo tiempo, sin atravesar la cremallera más de una vez, por ejemplo,

(let [feed (-> "http://..." clojure.zip/xml-zip clojure.xml/parse)] 
    (zipmap 
     (xml-> feed :channel :item :link text) 
     (xml-> feed :channel :item :title text))) 

... o una variación de la misma, que implica el mapeo de múltiples secuencias a una función que gradualmente construye un mapa con, por ejemplo, assoc.

No solo tengo que recorrer la secuencia varias veces, las secuencias también tienen estados separados, por lo que los elementos deben estar "alineados", por así decirlo. Es decir, en un caso más complejo que RSS, un elemento secundario puede faltar en un elemento particular, lo que hace que una de las secuencias sea más corta en uno (no hay espacios vacíos). Entonces, el resultado puede ser incorrecto.

¿Hay una manera mejor o es, de hecho, la manera que lo haces en Clojure?

Respuesta

3

¿Qué tal esto?

(reduce (fn [h item] 
      (assoc h (xml1-> item :title text) 
        (xml1-> item :link text))) 
     {} (xml-> feed :channel :item)) 
Cuestiones relacionadas