BTW, I should point out that zip-filter.xml/xml-> is surprisingly
syntaxy.
(xml-> loc
:CLUSTER :HOST :METRIC
(fn [loc]
[[(xml1-> (zip/up loc) (attr :NAME))
(xml1-> loc (attr :NAME))
(xml1-> loc (attr :VAL))
(xml1-> loc (attr :TN))]]))
In the above, I pass keywords, a function and calls to attr() to the
xml-> (and xml1->) functions. The keywords (like :CLUSTER, :HOST
and :METRIC) expand into things like
(tag= :CLUSTER)
which return functions that operate on zipper objects.
So if you're a bit overwhelmed by all the stuff that xml-> accepts,
just note that much of it is syntactic sugar, for your convenience.
Tayssir
On Dec 2, 7:41 pm, Tayssir John Gabbour <[email protected]>
wrote:
> 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/81b9e71effbaf6aa294...
>
> 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