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 <tayssir.j...@googlemail.com>
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 <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