babashka/examples/xml-example.clj
Bob a542227442
add examples for #324 and #369 [skip ci] (#911)
* add examples for:
- checking stdin for available input
- using data.xml lib

* fix some string contents left over from an XML change
2021-07-03 23:53:58 +02:00

78 lines
2.2 KiB
Clojure

; let's build up a little data structure to play with
(def pet-store-sexp
[:pet-store
[:family
[:owners
[:name "Terry Smith"]
[:name "Sam Smith"]
[:phone "555-1212"]]
[:animals
[:animal {:type "dog"} "Sparky"]]]
[:family
[:owners
[:name "Pat Jones"]
[:phone "555-2121"]]
[:animals
[:animal {:type "hamster"} "Oliver"]
[:animal {:type "cat"} "Kat"]]]])
; we can build XML from this
(def xml-str (xml/indent-str (xml/sexp-as-element pet-store-sexp)))
(println "Our XML as a string is:")
(println xml-str)
(comment xml-str is
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<pet-store>
<family>
<owners>
<name>Terry Smith</name>...")
; and then we can parse that XML back into a data structure
(def xml-tree (xml/parse-str xml-str))
#_"xml-tree is a nested associative structure:
{:tag :pet-store,
:attrs {},
:content
({:tag :family,
:attrs {},
:content ...})}"
; with a couple of quick helper functions...
(defn get-by-tag
"takes a seq of XML elements (or a 'root-ish' element) and a tag, filters by tag name, and gets the content of each"
[elems tag-name]
; if we get (presumably) a root element, wrap it in a vector so we can still
; filter by its tag
(if (xml/element? elems)
(recur [elems] tag-name)
(->> (filter #(= (:tag %) tag-name) elems)
(mapcat :content))))
(defn get-in-by-tag
"takes a seq of XML elements and a vector of tags, and drills into each
element by the tags, sort of like a mash-up of core/get-in and an XPath
lookup"
[elems tag-vec]
(reduce get-by-tag elems tag-vec))
; we can do things like...
(println "all the owner names:" (get-in-by-tag
xml-tree
[:pet-store :family :owners :name]))
(println "all the animal names:" (get-in-by-tag
xml-tree
[:pet-store :family :animals :animal]))
(println "all the phone numbers:" (get-in-by-tag
xml-tree
[:pet-store :family :owners :phone]))