1.2.0 permalink Arrow_down_16x16
  • (xml-> loc & preds)
The loc is passed to the first predicate. If the predicate returns
a collection, each value of the collection is passed to the next
predicate. If it returns a location, the location is passed to the
next predicate. If it returns true, the input location is passed to
the next predicate. If it returns false or nil, the next predicate
is not called.

This process is repeated, passing the processed results of each
predicate to the next predicate. xml-> returns the final sequence.
The entire chain is evaluated lazily.

There are also special predicates: keywords are converted to tag=,
strings to text=, and vectors to sub-queries that return true if
they match.

See the footer of zip-query.clj for examples.

1 Example top

  • ;;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!
Log in to add / edit an example.

See Also top

Log in to add a see also.

Plus_12x12 Minus_12x12 Source clojure/contrib/zip_filter/xml.clj:57 top

(defn xml->
  "The loc is passed to the first predicate.  If the predicate returns
  a collection, each value of the collection is passed to the next
  predicate.  If it returns a location, the location is passed to the
  next predicate.  If it returns true, the input location is passed to
  the next predicate.  If it returns false or nil, the next predicate
  is not called.

  This process is repeated, passing the processed results of each
  predicate to the next predicate.  xml-> returns the final sequence.
  The entire chain is evaluated lazily.

  There are also special predicates: keywords are converted to tag=,
  strings to text=, and vectors to sub-queries that return true if
  they match.

  See the footer of zip-query.clj for examples."
  [loc & preds]
    (zf/mapcat-chain loc preds
                     #(cond (keyword? %) (tag= %)
                            (string?  %) (text= %)
                            (vector?  %) (seq-test %))))
Vars in clojure.contrib.zip-filter.xml/xml->: cond defn keyword? string? vector?
Used in 0 other vars

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.

Log in to add a comment.