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 <shr3ks...@gmail.com> 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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to