2010-01-13 4 views
8

Ich möchte die Ergebnisse von drei Zip-Filter-Abfragen in einem XML-Baum kombinieren. Die XML-I wie folgt aussieht bin Parsen:Wie kombiniere ich Ergebnisse von Zip-Filter-Abfragen in einer XML-Struktur in Clojure?

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

Aus diesem Beispiel kann man sehen, dass <given_name> und <suffix> optional sind - nur <surname> erforderlich. Hier in liegt mein Problem - wenn ich laufen drei separate Abfragen die Antworten, die ich miteinander aus dem Gleichgewicht geraten sein bekommen:

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

Nach dem Ausführen dieser drei Abfragen ich mit drei Sequenzen, deren Mächtigkeiten gelassen werden nicht übereinstimmen; given_name und suffix wird Länge 1 sein, während surname wird Länge 2. Dies macht es mir unmöglich, die Komponenten der einzelnen Namen zu kombinieren. Ich muss eine einzelne Abfrage schreiben, die diese Namensverkettung während der Sequenzkonstruktion ausführt.

Ich schaue mir die sehr spärliche Dokumentation für clojure.contrib.zip-filter.xml an und kann nicht herausfinden, wie ich das machen könnte (oder ob es überhaupt möglich ist). Leider bin ich ein Clojure (und Lisp) Neuling! Kann jemand darauf hinweisen, wie ich eine Abfrage schreiben kann, die drei andere eingebettete Abfragen verketten wird?

+1

prüfen diese letzte Frage sO aus: http://stackoverflow.com/questions/2034550/Rückgabe-Mehrfachwerte-Verwendung-Clojure-Xml-Zipper –

Antwort

6

Sie können alle Teilbäume der Person in einem Schritt erhalten (xml-> xmlzip: publication: contributors: person_name) und dann die Namensteile erhalten, wenn sie existieren (xml1-> personzip: Nachname text) und sie mit dem Ergebnis kombinieren wollen wie so:

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

Ergebnisse ("Nachname A" "Nachname B, Gegeben B, Suffix B")

2

Ich nehme eine alternative Lösung zu

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

und dann jede <person_name> später verarbeiten.

Verwandte Themen