xml clojure clojure-contrib
heredata.zip

Clojure XML Parsing



clojure-contrib (2)

No puedo encontrar ninguna información sobre cómo analizar documentos xml y acceder a elementos.

He encontrado dos formas de analizar el documento xml

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

y

(parse-seq file)

pero parece que puedo encontrar información sobre cómo procesar la estructura resultante?

El archivo de origen hace referencia a zip-query.clj sobre cómo consultar el resultado, pero parece que también falta.


La respuesta anterior funciona, pero me resulta mucho más fácil usar clojure.data.zip.xml (solía ser clojure-contrib.zip-filter.xml antes de Clojure 1.3).

archivo:

myfile.xml :

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

código:

; 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")

Desafortunadamente, necesita establecer una dependencia en data.zip para obtener esta buena funcionalidad de lectura / filtro. Vale la pena la dependencia :) En lein sería (desde el 17 de agosto de 2013):

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

Y en cuanto a los documentos para data.zip.xml ... simplemente miro el archivo fuente relativamente pequeño here para ver qué es posible. Otra buena respuesta SO here , también.


Supongamos que tiene el siguiente xml para analizar en su archivo:

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

carga clojure.xml :

user=> (use ''clojure.xml)

cuando se analiza, el xml tendrá la siguiente estructura:

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

y luego puede buscar el contenido del archivo para obtener el contenido de los low-node :

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

Del mismo modo, si quisiera tener acceso a toda la lista de información en low-node, cambiaría :when predicate to (= (: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"]})

Esto funciona porque las palabras clave pueden funcionar como funciones. Consulte Preguntas sobre listas y otras cosas en Clojure y Data Structures: palabras clave