Hi!
Taking minor liberties with your code (for clarity), the following
gives pretty much the same result as your handle-xml function:
(ns blah
(:require [clojure.xml :as xml]
[clojure.zip :as zip])
(:use clojure.contrib.zip-filter.xml))
(defn my-test []
(doseq [x (xml-> (zip/xml-zip (xml/parse "/my-path-to/GANGLIA.xml"))
:CLUSTER :HOST :METRIC
(fn [loc]
[[(xml1-> (zip/up loc) (attr :NAME))
(xml1-> loc (attr :NAME))
(xml1-> loc (attr :VAL))
(xml1-> loc (attr :TN))]]))]
(apply println x)))
The call to zip/xml-zip creates a zipper object, a simple trick to
travel around xml.
Each argument to xml-> (after the first) drills down the tree. The
last argument, once I've drilled down to the :METRIC node, collects
the attributes you're interested in.
The sourcecode has handy examples to play along with. For your
reference:
http://github.com/richhickey/clojure-contrib/blob/81b9e71effbaf6aa2945cd684802d87c762cdcdd/src/clojure/contrib/zip_filter/xml.clj#L94
Note: If you print the zipper object, its representation will be
pretty, pretty big. If that's a problem, remember to call zip/node at
the end, as per the examples. Or do the crazy thing I do, which is to
customize print-method (specifying each zipper object's :type
metadata), so it'll have a tiny representation like:
#<ganglia gmond>
Hope that makes sense,
Tayssir
On Dec 2, 4:51 pm, Dennis <[email protected]> wrote:
> Howdy,
>
> Being new to clojure, I am having a difficult time parsing XML in an elegant
> manner. I am pulling metric information from a ganglia server as XML and
> then parsing it. The below function works but it makes me feel icky. I was
> hoping for some tips.
>
> The "dc" variable contains a map with some data center information (not
> really interesting), and the "stream" variable comes from http.agent.
>
> (defn handle-xml [dc stream]
> (let [xml-out (xml-seq (parse (http/stream stream)))]
> (doseq [x xml-out]
> (doseq [y (:content x)]
> (doseq [z (:content y)]
> (doseq [a (:content z)]
> (println (:dc dc) (:NAME (:attrs z)) (:NAME (:attrs a)) (:VAL (:attrs
> a)) (:TN (:attrs a)))))))))
>
> The XML is of the form:
> ganglia
> multiple clusters
> multiple hosts
> multiple metrics
>
> Example of the XML:
> <GANGLIA_XML VERSION="3.0.7" SOURCE="gmond">
> <CLUSTER NAME="cluster.example.com" LOCALTIME="1258396022"
> OWNER="unspecified" LATLONG="unspecified" URL="unspecified">
> <HOST NAME="server.example.com" IP="127.0.0.1" REPORTED="1258396019" TN="3"
> TMAX="20" DMAX="86400" LOCATION="unspe
> cified" GMOND_STARTED="1255757736">
> <METRIC NAME="disk_total" VAL="1320.124" TYPE="double" UNITS="GB" TN="6684"
> TMAX="1200" DMAX="0" SLOPE="both" SOURCE="gmond"/>
> <METRIC NAME="cpu_speed" VAL="2493" TYPE="uint32" UNITS="MHz" TN="682"
> TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
> ...
>
> Thanks,
> Dennis
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en