Fork me on GitHub
#ring-swagger
<
2019-08-14
>
joefromct17:08:18

thanks for that, i think i have something working. Hereā€™s what i have so far for adding xml as a new format to a muuntaja instance:

ikitommi17:08:44

nice. what kind of data does the format return for the handler?

ikitommi17:08:01

is it a json-like map?

joefromct17:08:15

just a string at the moment, but iā€™ll have specs to make sure itā€™s well-formed xml, i donā€™t have a schema at the moment so maybe i can plug that in later too

joefromct17:08:47

i was unsure on line 10 for the (slurp data) bit but i donā€™t know if there is a better way to do itā€¦ surprised everyone else is lucky enough to not be using xml šŸ˜‰

ikitommi17:08:49

<xml><kikka>1</kikka></xml> => {:xml {:kikka 1}}?

joefromct17:08:29

yeah i was tinkering with that too, as per here https://github.com/joefromct/clj-xmltojson

ikitommi17:08:32

haha. using that in some legacy, but using a custom endpoint to read that. not as a first class format

joefromct17:08:53

^ itā€™s a bit more json looking than what you get from clojure.xml iirc

ikitommi17:08:32

nice! I think we wrote similar small too when last needed that.

ikitommi17:08:45

~lossless transformation there and back.

joefromct17:08:05

šŸ™‚ sounds good, thanks for your help

ikitommi17:08:23

oh, itā€™s on internet šŸ˜®

joefromct17:08:43

must be private, i get a 404 ?

ikitommi17:08:36

oh, itā€™s private. last modified 4years ago. kinda horrible, that clj-xmltojson must be better.

ikitommi17:08:40

(declare xml->clj)

(defn- attr-name [k] (keyword (str "#" (name k))))
(defn- decorate-attrs [m] (zipmap (map attr-name (keys m)) (vals m)))
(defn- merge-to-vector [m1 m2] (merge-with #(flatten [%1 %2]) m1 m2))
(defn- childs? [v] (map? (first v)))
(defn- lift-text-nodes [m] (if (= (keys m) [:##text]) (val (first m)) m))
(defn- parts [{:keys [attrs content]}]
  (merge {} (decorate-attrs attrs)
         (if (childs? content)
           (reduce merge-to-vector (map xml->clj content))
           (hash-map :##text (first content)))))

(defn xml->clj
  ([xml] (hash-map (:tag xml) (-> xml parts lift-text-nodes)))
  ([xml schema]
   (xmls/->clj (xml->clj xml) schema)))

ikitommi17:08:48

but thatā€™s about the source.

joefromct17:08:49

wellā€¦ no promises there. I think the idea is sound, but i have a nasty postwalk iā€™ve been thinking about trying to remove somehow for performance reasons. There is this clever bit of the python equivelent library that has a concept of ā€œforce listā€ for single-entry xml elementsā€¦. to force to a vector. The only way i could add the ā€œforce listā€ functionality was with a postwalk

joefromct17:08:51

that i could think of

ikitommi17:08:35

force list, doall?

joefromct17:08:02

basically, xml like this: <xml> <planes> <plane>jumbo</plane> </planes> </xml> you could pass a set into clj-xmltojson that would yield a vector of length one for the ā€œjumbo planeā€

joefromct17:08:47

thus, forcing it to a list ā€¦ when you donā€™t have an xsd and you need to make sure planes is always a list. This would be ā€œinferredā€ to be a list: <xml> <planes> <plane>jumbo</plane> <plane>f35</plane> </planes> </xml>

ikitommi17:08:52

you would like them all to be lists?

joefromct17:08:01

Yes, when they are deliberately passed in via the force-list parameter (set) itā€™s pretty nasty code, i should find time to rewrite it and update the readme. embarrassed that somebody is actually looking at atm.

joefromct17:08:55

hereā€™s a specific example from my repl

joefromct17:08:42

you can see the second call to xml->json with the force-list set ensures that ā€œ:planeā€ is always a list/vector in the output

joefromct17:08:26

so anyway, iā€™ll rewrite it one of these days and try to make the readme decent.