Pergunta

Quero combinar os resultados de três consultas de filtro zip em uma árvore XML. O XML que eu estou analisando se parece com o seguinte:

<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 deste exemplo, você pode ver isso <given_name> e <suffix> são opcionais - apenas <surname> É necessário. Aqui estão no meu problema - se eu executar três consultas separadas, as respostas que recebo ficarão fora de ordem uma com a outra:

(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)

Depois de executar essas três consultas, ficarei com três seqüências cujas cardinalidades não correspondem; given_name e suffix será de comprimento 1 enquanto surname será o comprimento 2. Isso torna impossível combinar os componentes de cada nome. Preciso escrever uma única consulta que executará esse nome concatenação durante a construção de sequência.

Estou olhando para a documentação muito esparsa para clojure.contrib.zip-filter.xml e não consigo descobrir como eu poderia fazer isso (ou se é possível). Infelizmente, sou um novato (e Lisp)! Alguém pode apontar como posso escrever uma consulta que concatenará três outras consultas incorporadas?

Foi útil?

Solução

Você pode obter todas as subáridas de uma pessoa em uma etapa (xml-> xmlzip: Publicação: Colaboradores: Person_name), em seguida, obtenha as partes do nome se elas existirem (XML1-> Personzip: Sobrenome Texto) e combiná-las com o resultado que desejar:

(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)))

Resulta em ("Sobrenome A" "Sobrenome B, dado B, Sufixo B")

Outras dicas

Suponho que uma solução alternativa é

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

e então processe cada um <person_name> mais tarde.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top