65 votes

Clojure XML Parsing

Je ne trouve aucune information sur la façon d'analyser les documents XML et les éléments d'accès.

J'ai trouvé deux façons d'analyser le document XML

 (clojure.zip/xml-zip (clojure.xml/parse file))
 

et

 (parse-seq file)
 

mais je peux sembler trouver n'importe quelle information sur la façon dont traiter la structure résultante?

Le fichier source fait référence à zip-query.clj sur la manière d’interroger le résultat, mais il semble manquer aussi.

82voto

Pinochle Points 3442

Supposons que vous disposez des éléments xml à analyser dans votre fichier:

<high-node>
   <low-node>my text</low-node>
</high-node>

vous chargez clojure.xml:

user=> (use 'clojure.xml)

lorsque analysée, le xml aura la structure suivante:

{:tag :high-node, :attrs nil, :content [{:tag :low-node, :attrs nil, :content ["my text"]}]}

et puis vous pouvez seq sur le contenu du fichier pour obtenir le contenu de l' low-node:

user=> (for [x (xml-seq 
              (parse (java.io.File. file)))
                 :when (= :low-node (:tag x))]
         (first (:content x)))

("my text")

De même, si vous voulez avoir accès à l'ensemble de la liste des informations sur les bas-nœud, vous pouvez modifier l' :when prédicat (= (:high-node (:tag x))):

user=> (for [x (xml-seq 
              (parse (java.io.File. file)))
                 :when (= :high-node (:tag x))]
         (first (:content x)))

({:tag :low-node, :attrs nil, :content ["my text"]})

Cela fonctionne parce que les mots clés peuvent fonctionner comme des fonctions. Voir les Questions sur les listes et d'autres choses en Clojure et Structures de Données: les mots clés

56voto

overthink Points 9471

La réponse ci-dessus fonctionne, mais je trouve ça beaucoup plus facile à utiliser, clojure.data.zip.xml (utilisé pour être clojure-contrib.zip-filter.xml avant Clojure 1.3).

fichier:

myfile.xml:

<songs>
  <track id="t1"><name>Track one</name></track>
  <track id="t2"><name>Track two</name></track>
</songs>

code:

; Clojure 1.3
(ns example
  (:use [clojure.data.zip.xml :only (attr text xml->)]) ; dep: see below
  (:require [clojure.xml :as xml]
            [clojure.zip :as zip]))

(def xml (xml/parse "myfile.xml"))
(def zipped (zip/xml-zip xml))
(xml-> zipped :track :name text)       ; ("Track one" "Track two")
(xml-> zipped :track (attr :id))       ; ("t1" "t2")

Malheureusement, vous avez besoin de tirer dans une dépendance sur data.zip pour obtenir cette belle lecture/fonctionnalités du filtre. Il vaut la peine de la dépendance :) En lein , il serait (à compter du 17-Aug-2013):

[org.clojure/data.zip "0.1.1"]

Et comme pour les docs pour data.zip.xml ... je viens de regarder le relativement petit fichier source ici pour voir ce qui est possible. Un autre bon ALORS répondez ici, trop.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X