Thanks Abishek, this did help!

It pretty much worked as-is for me, I only needed one small change.

It was that the get-mods-for-iva function below returns a seq whose
first element is the matches and next element(s) were my entire xml
content - easily rectified with (first (xz/xml1-> x-zip...

On Tue, Aug 31, 2010 at 11:25 PM, Abhishek Reddy <arbs...@gmail.com> wrote:
> Hi Peter,
>
> The library clojure.contrib.zip-filter is pretty good at this sort of thing.
> For example:
>
> (require '[clojure.xml :as xml])
> (require '[clojure.contrib.zip-filter.xml :as zx])
> (require '[clojure.zip :as zip])
>
> (defn get-mods-for-iva
>   "Returns the <mods> node if one exists under a <version> node
>    whose inner-ver-attrib matches test-iva.  Otherwise, returns nil."
>   [x-zip test-iva]
>   (zx/xml1-> x-zip
>              (zx/tag= :version)
>              (zx/attr= :inner-ver-attrib test-iva)
>              (zx/tag= :type)
>              (zx/tag= :mods)))
>
> (defn get-replacement-values
>   "Returns a seq of <mods> nodes if available in x-file for versions
>    1.4 and 1.6 respectively."
>   [x-file]
>   (let [x-zip (zip/xml-zip (xml/parse x-file))
>         test-ivas ["1.4" "1.6"]]
>     (map (partial get-mods-for-iva x-zip) test-ivas)))
>
> ``clojure.contrib.zip-filter.xml/xml1->'' filters an xml-zip tree
> using predicates on tags, attributes or text values of nodes.  You can
> chain predicates together (like in ``clojure.core/->'') to navigate
> trees conditionally.  If a predicate returns false or nil, the whole
> form returns nil, so you know there is no complete match.
>
> In the ``get-mods-for-iva'' function above, we start with the complete
> tree ``x-zip'', and filter for <version>, then
> <version inner-ver-attrib=test-iva>, then <type>, and finally <mods>.
>
> In ``get-replacement-values'', we parse the XML file and derive an
> xml-zip tree from it.  We then call ``get-mods-for-iva'' for each of
> the pre-defined versions, and return a seq of their results.
>
> This may not be the best solution, and I may have misinterpreted your
> exact XML structure, but the code shows a simple, functional style.
> We try to avoid do* forms and side effects (printing during calculation)
> where possible, collecting results of function calls instead.
>
> I hope it helps!
>
>
> On Wed, Sep 1, 2010 at 7:10 AM, Peter <buckmeist...@gmail.com> wrote:
>>
>> Hi-
>>
>> I'm brand new to Clojure and FP, reading a bunch and working on my
>> first programming task (reading in values from an xml file and a text
>> file and then creating a new text file with some lines/sections of the
>> original text file replaced based on the content of the xml).
>>
>> I found some helpful info here:
>> http://www.chrisumbel.com/article/clojure_xml_parsing_xml-seq
>> on reading the xml file, but I'm a couple more levels deep than that
>> article. I don't know much about Clojure yet, but I have a feeling I'm
>> not doing it the right/idiomatic/best way. I've basically got three
>> nested calls to doseq, and I think it is mostly due to my own
>> unfamiliarity with Clojure and the better options I would have to do
>> this in FP.
>>
>> I'm getting the ver tag in the xml then checking one of its attribs to
>> make sure I'm pulling from the version I want, and then I get the
>> content of the mods tag. I've tried to somewhat simplify this case so
>> the following isn't tested after being extracted from my sandbox.
>>
>> TIA!
>>
>> (defn- dig-through-struct
>>  "Hides a pair of nested doseq calls from my main function"
>>  [xml-as-struct]
>>  (doseq [y (:content xml-as-struct)
>>          :when (= :type (:tag y))]
>>    (doseq [z (:content y)
>>            :when (= :mods (:tag z))]
>>    (println "The content I want" (:content z)))))
>>
>> (defn- get-replacement-values
>>  "Pulls from xml values we want to replace/update/add"
>>  [x-file]
>>  (let [xml-file (File. x-file)]
>>    (xml-seq (parse xml-file))
>>    (for [testing-ver `("1.4" "1.6")]
>>      (doseq [x (xml-seq (parse xml-file))
>>              :when (= :ver (:tag x))]
>>        (let [iva (:inner-ver-attrib (:attrs x))]
>>          (if (= testing-ver iva)
>>            (dig-through-struct x testing-ver iva)
>>            (println "Did not match the ver we want" testing-ver iva)))))))
>>
>> And this is my xml:
>>
>> <proj
>> bunch of attribs
>> ...>
>>
>> <ver
>> inner-ver-attrib=1.4 (or 1.6 etc, this is a tag I'm interested in
>> conditionally checking)
>> bunch of attribs
>> ...>
>>
>> <type
>> bunch of attribs
>> ...>
>>
>>  <mods>
>>    <remove>
>>      <entry-name>files</entry-name>
>>      <entry>path_old\foo_old.c</entry>
>>      <entry>path_old1\foo_old.h</entry>
>>    </remove>
>>    <add>
>>      <entry-name>files</entry-name>
>>      <entry>path\foo.c</entry>
>>      <entry>path1\foo.h</entry>
>>    </add>
>>    <change>
>>      <entry-name>opts</entry-name>
>>      <from>-bar=1</from>
>>      <to>-bar=2</to>
>>    </change>
>>  </mods>
>> </type></version</project>
>>
>> --
>> 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
>
>
> --
> Abhishek Reddy
> http://abhishek.geek.nz
>
>
> --
> 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



-- 
The king’s heart is like a stream of water directed by the Lord; He
guides it wherever He pleases.

-- 
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