;;convenience method for parsing up an xml tree
(defn parse-str [s]
(zip/xml-zip (xml/parse (new org.xml.sax.InputSource
(new java.io.StringReader s)))))
;;load a simple xml-tree from string
(def sometree (parse-str "<TopNode id='1'><ParentNode id='2'><ChildrenNode id='3'/></ParentNode></TopNode>"))
=> [{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]} nil]
;;now we go down the tree to ParentNode, the tree looks quite turned upside down as it has the form {:l "left part of tree" :p "what the parent looks like" :r "what the right part looks like"}
(xml-> sometree zip/down)
=>
([{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}
{:l [], :pnodes
[{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]}], :ppath nil,
:r nil}])
;;This renders nothing, since we always select children nodes
(xml-> sometree :TopNode)
=>()
;;This one also ends up as empty as ChildrenNode is a grandchildren compared to the topnode
(xml-> sometree :ChildrenNode)
=>()
;;Lets now try ParentNode!
(xml-> sometree :ParentNode)
=>
([{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}
{:l [], :pnodes
[{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]}], :ppath nil, :r nil}])
;;Observe that the first thing we get is the ParentNode and it's ChildrenNode. To the left "back" we see the tree as it would be if we when up one level, to the right there's nothing.
;;Query: What's the id's of (all) the ChildrenNode under the parent node?
;;we have the convenience-method (attr :attribute-keyword) to help:
(xml-> sometree :ParentNode :ChildrenNode (attr :id))
("3")
;;Go to the ParentNode, ChildrenNode, remove the ChildrenNode and return RootNode
(xml-> sometree :ParentNode :ChildrenNode zip/remove zip/root)
({:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content nil}]})
;;Ta da! - No ChildrenNode left!
;;convenience method for parsing up an xml tree
(defn parse-str [s]
(zip/xml-zip (xml/parse (new org.xml.sax.InputSource
(new java.io.StringReader s)))))
;;load a simple xml-tree from string
(def sometree (parse-str "<TopNode id='1'><ParentNode id='2'><ChildrenNode id='3'/></ParentNode></TopNode>"))
=> [{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]} nil]
;;now we go down the tree to ParentNode, the tree looks quite turned upside down as it has the form {:l "left part of tree" :p "what the parent looks like" :r "what the right part looks like"}
(xml-> sometree zip/down)
=>
([{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}
{:l [], :pnodes
[{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]}], :ppath nil,
:r nil}])
;;This renders nothing, since we always select children nodes
(xml-> sometree :TopNode)
=>()
;;This one also ends up as empty as ChildrenNode is a grandchildren compared to the topnode
(xml-> sometree :ChildrenNode)
=>()
;;Lets now try ParentNode!
(xml-> sometree :ParentNode)
=>
([{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}
{:l [], :pnodes
[{:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content
[{:tag :ChildrenNode, :attrs {:id "3"}, :content nil}]}]}], :ppath nil, :r nil}])
;;Observe that the first thing we get is the ParentNode and it's ChildrenNode. To the left "back" we see the tree as it would be if we when up one level, to the right there's nothing.
;;Query: What's the id's of (all) the ChildrenNode under the parent node?
;;we have the convenience-method (attr :attribute-keyword) to help:
(xml-> sometree :ParentNode :ChildrenNode (attr :id))
("3")
;;Go to the ParentNode, ChildrenNode, remove the ChildrenNode and return RootNode
(xml-> sometree :ParentNode :ChildrenNode zip/remove zip/root)
({:tag :TopNode, :attrs {:id "1"}, :content
[{:tag :ParentNode, :attrs {:id "2"}, :content nil}]})
;;Ta da! - No ChildrenNode left!
Comments top
1 comment(s) for xml->.
This library is moved to clojure/data.zip ( https://github.com/clojure/data.zip ) in the 1.3.0 version of clojure.