Question

Je veux combiner les résultats de trois requêtes zip-filtre sur un arbre XML. Le XML J'analyse ressemble à ceci:

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

De cet exemple, vous pouvez voir que <given_name> et <suffix> sont facultatifs - seulement <surname> est nécessaire. Ici, en voici mon problème - si je lance trois requêtes distinctes les réponses que je reçois seront en décalage avec l'autre:

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

Après avoir exécuté ces trois requêtes, je vais à gauche avec trois séquences dont cardinalités ne correspondent pas; given_name et suffix seront longueur 1 tandis que surname sera longueur 2. Cela me rend impossible de combiner les composants de chaque nom. Je dois écrire une seule requête qui effectuera cette concaténation de nom lors de la construction de la séquence.

Je regarde la documentation très clairsemée pour clojure.contrib.zip-filter.xml et ne peut pas comprendre comment je pouvais le faire (ou s'il est même possible). Malheureusement, je suis un Clojure (et Lisp) débutant! Quelqu'un peut-il indiquer comment je peux écrire une requête qui concaténer trois autres requêtes intégrées?

Était-ce utile?

La solution

Vous pouvez obtenir toutes les personnes sous-arbres en une seule étape (xml-> xmlzip: publication: collaborateurs: person_name), puis obtenir les pièces de nom si elles existent (xml1-> personzip: texte de nom de famille) et les combiner au résultat que vous voulez comme ceci:

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

Les résultats de ( "Nom A" "Nom B, B donné, le suffixe B")

Autres conseils

Je suppose une autre solution consiste à

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

puis traiter chaque <person_name> plus tard.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top