data.zip

Not returning expected result for 'tag='

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
     :dependencies [[org.clojure/clojure "1.5.1"]
                     [org.clojure/data.zip "0.1.1"]]
  • Patch:
    Code and Test

Description

Setup:

(require '[clojure.xml :as xml])
(require '[clojure.zip :as zip])
(require '[clojure.data.zip.xml :as dzx])

(def s "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<result>\n <status>success</status>\n <message>success</message>\n <format>xml</format>\n <language>en</language>\n <ip>208.67.220.220</ip>\n <country_code>US</country_code>\n <country>United States</country>\n <region>California</region>\n <city>San Francisco</city>\n <latitude>37.7757</latitude>\n <longitude>-122.3952</longitude>\n <zip_code>94107</zip_code>\n <timezone>-08:00</timezone>\n <localtime>2014-04-17 06:52:45</localtime>\n</result>\n")

(def x (xml/parse (org.xml.sax.InputSource. (java.io.StringReader. s))))
(def z (zip/xml-zip x))

Works as expected:

(dzx/xml1-> z :ip dzx/text)
;; "208.67.220.220"

(dzx/xml1-> z :status dzx/text)
;; "success"

Doesn't seem to work as expected:

(dzx/xml1-> z :result)
;; nil   (expected something not nil)

(dzx/xml1-> z :result :status dzx/text)
;; nil   (expected "success")

Activity

Hide
Erik Assum added a comment -

Looking at the definition of tag=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L26

it does some more logic (which I don’t understand) than both
attr=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L21

and
text=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L44

So I’m curious as to why tag= cannot be implemented as:

(defn tag= [tagname]
  (fn [loc]
    (= tagname (:tag (zip/node loc)))))
Show
Erik Assum added a comment - Looking at the definition of tag= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L26 it does some more logic (which I don’t understand) than both attr= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L21 and text= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L44 So I’m curious as to why tag= cannot be implemented as:
(defn tag= [tagname]
  (fn [loc]
    (= tagname (:tag (zip/node loc)))))
Hide
Erik Assum added a comment -

Looking at the definition of tag=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L26

it does some more logic (which I don’t understand) than both
attr=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L21

and
text=
https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L44

So I’m curious as to why tag= cannot be implemented as:

(defn tag= [tagname]
  (fn [loc]
    (= tagname (:tag (zip/node loc)))))
Show
Erik Assum added a comment - Looking at the definition of tag= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L26 it does some more logic (which I don’t understand) than both attr= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L21 and text= https://github.com/clojure/data.zip/blob/master/src/main/clojure/clojure/data/zip/xml.clj#L44 So I’m curious as to why tag= cannot be implemented as:
(defn tag= [tagname]
  (fn [loc]
    (= tagname (:tag (zip/node loc)))))
Hide
Erik Assum added a comment -

A reason for this would be that the tests fail... but why?

Show
Erik Assum added a comment - A reason for this would be that the tests fail... but why?
Hide
Erik Assum added a comment -

So it seems like the problem is that you get an empty match if you try to match a tag on the first element in the xml:

(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> atom2 :feed ) '()))) ; fail

(deftest dzip-3-second-node
  (is (= (xml-> atom2 :foo text) '("bar")))) ; pass
Show
Erik Assum added a comment - So it seems like the problem is that you get an empty match if you try to match a tag on the first element in the xml:
(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> atom2 :feed ) '()))) ; fail

(deftest dzip-3-second-node
  (is (= (xml-> atom2 :foo text) '("bar")))) ; pass
Hide
Erik Assum added a comment - - edited

So, if you do

(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> (clojure.data.zip/auto false atom2) :feed ) '())))

(deftest dzip-3-second-node
  (is (= (xml-> atom2 :foo text) '("bar"))))

the tests will pass. Whereas if you

(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> (clojure.data.zip/auto false atom2) :feed ) '())))

(deftest dzip-3-second-node
  (is (= (xml-> (clojure.data.zip/auto false atom2) :foo text) '("bar"))))

zip-3-second-node will fail.

Show
Erik Assum added a comment - - edited So, if you do
(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> (clojure.data.zip/auto false atom2) :feed ) '())))

(deftest dzip-3-second-node
  (is (= (xml-> atom2 :foo text) '("bar"))))
the tests will pass. Whereas if you
(def atom2 (parse-str "<feed>
<foo>bar</foo></feed>"))

(deftest dzip-3-first-node
  (is (not= (xml-> (clojure.data.zip/auto false atom2) :feed ) '())))

(deftest dzip-3-second-node
  (is (= (xml-> (clojure.data.zip/auto false atom2) :foo text) '("bar"))))
zip-3-second-node will fail.
Hide
Erik Assum added a comment -

The problem was that tag= checked for a match either in the zippers node or in its
children. The patch solves this by first looking for a match in the node,
and if that fails, look for a match in the children.

Show
Erik Assum added a comment - The problem was that tag= checked for a match either in the zippers node or in its children. The patch solves this by first looking for a match in the node, and if that fails, look for a match in the children.
Hide
Alex Miller added a comment -

Thanks, applied for next release!

Show
Alex Miller added a comment - Thanks, applied for next release!

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: