ring-swagger & compojure-api
ikitommi 2019-08-14T17:34:58.003500Z

@joefromct there is a guide in https://github.com/metosin/muuntaja/blob/master/doc/Creating-new-formats.md for adding new formats.

joefromct 2019-08-14T17:38:18.004500Z

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:

ikitommi 2019-08-14T17:40:44.006300Z

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

ikitommi 2019-08-14T17:41:01.006800Z

is it a json-like map?

joefromct 2019-08-14T17:41:15.007400Z

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

joefromct 2019-08-14T17:41:47.008400Z

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 😉

ikitommi 2019-08-14T17:41:49.008500Z

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

joefromct 2019-08-14T17:42:29.009400Z

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

ikitommi 2019-08-14T17:42:32.009600Z

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

joefromct 2019-08-14T17:42:53.010Z

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

ikitommi 2019-08-14T17:43:32.010500Z

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

ikitommi 2019-08-14T17:43:45.010900Z

~lossless transformation there and back.

joefromct 2019-08-14T17:44:05.011300Z

🙂 sounds good, thanks for your help

ikitommi 2019-08-14T17:44:23.011600Z

oh, it’s on internet 😮

ikitommi 2019-08-14T17:44:24.011800Z


joefromct 2019-08-14T17:44:43.012100Z

must be private, i get a 404 ?

ikitommi 2019-08-14T17:45:36.012900Z

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

ikitommi 2019-08-14T17:45:40.013100Z

(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)))

ikitommi 2019-08-14T17:45:48.013500Z

but that’s about the source.

joefromct 2019-08-14T17:46:49.014900Z

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

joefromct 2019-08-14T17:46:51.015100Z

that i could think of

joefromct 2019-08-14T17:46:53.015300Z

so far

ikitommi 2019-08-14T17:47:35.016200Z

force list, doall?

joefromct 2019-08-14T17:48:02.016700Z

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”

joefromct 2019-08-14T17:48:47.017500Z

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>

ikitommi 2019-08-14T17:49:52.018300Z

you would like them all to be lists?

joefromct 2019-08-14T17:51:01.019200Z

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.

joefromct 2019-08-14T17:55:55.020Z

here’s a specific example from my repl

joefromct 2019-08-14T17:56:42.020900Z

you can see the second call to xml-&gt;json with the force-list set ensures that “:plane” is always a list/vector in the output

joefromct 2019-08-14T17:57:26.021500Z

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