Thanks a bunch, this has been very helpful. -- Dennis
On Wed, Dec 2, 2009 at 1:03 PM, Tayssir John Gabbour < tayssir.j...@googlemail.com> wrote: > 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<clojure%2bunsubscr...@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- 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