Domanda

Voglio combinare i risultati di tre interrogazioni zip-filtro su un albero XML. L'XML sto parsing assomiglia a questo:

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

Da questo esempio si può vedere che <given_name> e <suffix> sono opzionali - è richiesto solo <surname>. Qui giace nel mio problema - se corro tre query separate le risposte che ottengo sarà fuori forma con l'altro:

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

Dopo l'esecuzione di queste tre domande sarò lasciato con tre sequenze la cui cardinalità non corrispondono; given_name e suffix saranno lunghezza 1 mentre surname sarà lunghezza 2. Questo rende impossibile per me per combinare i componenti di ogni nome. Ho bisogno di scrivere una singola query che eseguirà questo nome concatenazione durante la costruzione della sequenza.

Sto guardando la documentazione molto scarsa per clojure.contrib.zip-filter.xml e non riesco a capire come avrei potuto fare questo (o se è ancora possibile). Purtroppo io sono un Clojure (e Lisp) newbie! Chiunque può segnalare come posso scrivere una query che concatenare altre tre domande incorporati?

È stato utile?

Soluzione

È possibile ottenere tutte le sottostrutture persona in un solo passaggio (XML> xmlzip: pubblicazione: contributori: PERSON_NAME) quindi ottenere le parti di nome, se esistono (xml1-> personzip: il cognome del testo) e combinarli al risultato che si desidera in questo modo:

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

Risultati in ( "Cognome A" "B Cognome, Data B, suffisso B")

Altri suggerimenti

Credo che una soluzione alternativa è quella di

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

e quindi elaborare ogni <person_name> in seguito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top