¿Cómo combino los resultados de las consultas con cierre de filtro en un árbol XML en Clojure?

StackOverflow https://stackoverflow.com/questions/2057797

Pregunta

quiero combinar los resultados de tres consultas cremallera de filtro en un árbol XML. El XML estoy de análisis es el siguiente:

<someroot>
  <publication>
    <contributors>
      <person_name>
        <surname>Surname A</surname>
      </person_name>
      <person_name>
        <given_name>Given B</given_name>
        <surname>Surname B</surname>
        <suffix>Suffix B</suffix>
      </person_name>
    </contributors>
  </publication>
</someroot>

A partir de este ejemplo se puede ver que <given_name> y <suffix> son opcionales - sólo se requiere <surname>. Aquí reside en mi problema - si me quedo tres consultas separadas las respuestas que recibo estarán fuera de orden entre sí:

(xml-> xml :publication :contributors :person_name :given_name text)
(xml-> xml :publication :contributors :person_name :surname text)
(xml-> xml :publication :contributors :person_name :suffix text)

Después de ejecutar estas tres preguntas que se quedará con tres secuencias cuya cardinalidad no coinciden; given_name y suffix serán longitud 1, mientras que surname será la longitud 2. Esto hace que sea imposible para mí para combinar los componentes de cada nombre. Tengo que escribir una sola consulta que llevará a cabo este nombre concatenación durante la construcción de la secuencia.

Estoy mirando la documentación muy escasa para clojure.contrib.zip-filter.xml y no puedo imaginar cómo podría hacer esto (o si incluso es posible). Por desgracia yo soy muy novato Clojure (y Lisp)! ¿Puede alguien señalar cómo puedo escribir una consulta que concatenar otras tres consultas incrustados?

¿Fue útil?

Solución

Usted puede obtener todos los subárboles persona en un solo paso (xml-> xmlzip: publicación: colaboradores: person_name) a continuación, obtener los nombres de las partes si es que existen (xml1-> personzip: Texto apellido) y combinarlos con el resultado que desea de esta manera:

(use 'clojure.contrib.zip-filter.xml)
(defn format-name
  [surname given suffix]
  (str surname (if given (str ", " given)) (if suffix (str ", " suffix))))
(defn get-names
  [xz] 
  (map (juxt 
         #(xml1-> % :surname text) 
         #(xml1-> % :given_name text) 
         #(xml1-> % :suffix text))
     (xml-> xz :publication :contributors :person_name)))
(let [x (clojure.zip/xml-zip (clojure.xml/parse "foo.xml"))] 
  (map (partial apply format-name) (get-names x)))

Los resultados en ( "Apellido A" "Apellido B, dado B, Sufijo B")

Otros consejos

supongo una solución alternativa es

(xml-> xml :publication :contributors :person_name)

y luego procesar cada <person_name> más adelante.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top