0

I'm a bit new to Clojure and wondering how to convert this Enlive Object to JSON Object.

I parsed through a XML file using the parse method as below:

(def xml-parser
  (parse "<Vehicle><Model>Toyota</Model><Color>Red</Color><Loans><Reoccuring>Monthly</Reoccuring><Owners><Owner>Bob</Owner></Owners></Loans><Tires><Model>123123</Model><Size>23</Size></Tires><Engine><Model>30065</Model></Engine></Vehicle>"))

And obtained an Enlive Object like so:

{:tag :Vehicle,
 :attrs nil,
 :content
 [{:tag :Model, :attrs nil, :content ["Toyota"]}
  {:tag :Color, :attrs nil, :content ["Red"]}
  {:tag :Loans,
   :attrs nil,
   :content
   [{:tag :Reoccuring, :attrs nil, :content ["Monthly"]}
    {:tag :Owners,
     :attrs nil,
     :content [{:tag :Owner, :attrs nil, :content ["Bob"]}]}]}
  {:tag :Tires,
   :attrs nil,
   :content
   [{:tag :Model, :attrs nil, :content ["123123"]}
    {:tag :Size, :attrs nil, :content ["23"]}]}
  {:tag :Engine,
   :attrs nil,
   :content [{:tag :Model, :attrs nil, :content ["30065"]}]}]}

And I would like to be able to convert it into an JSON Object as below:

{:Vehicle {:Model "Toyota"
           :Color "Red"
           :Loans {:Reoccuring "Monthly"
                   :Owners {:Owner "Bob"}}
           :Tires {
                   :Model 123123
                   :Size 23}
           :Engine {:Model 30065}}
}

I apologize if the vocabulary used is not completely accurate

I'm having trouble with this step of conversion. Thank you for your help in advance.

Jett
  • 781
  • 1
  • 14
  • 30
  • 2
    Your target object is a Clojure nested map; it is not a JSON string (i.e. you don't have any double-quotes). Also, the keys are all Clojure keywords, not JSON dictionary keys (strings). – Alan Thompson Feb 03 '21 at 04:39
  • 1
    Please add the code you have tried and how it failed (e.g. errors, stacktraces, logs, ...) so we can improve on it. – cfrick Feb 03 '21 at 08:48
  • In https://stackoverflow.com/questions/66016572/how-to-convert-xml-to-edn-in-clojure you are asking to create EDN (but your example is technically EDN but looks way more like the CLJ version of YAML). And now you are asking for JSON, but your example is EDN. The answer of above link provides a way to build the exact result you are asking here for. Is your actual question how to turn EDN into JSON? – cfrick Feb 03 '21 at 16:04

1 Answers1

2

this should be as simple, as recursive content transformation:

(defn process-rec [{:keys [tag content]}]
  {tag (if (string? (first content))
         (first content)
         (apply merge (map process-rec content)))})

or like this, with deeper destructuring:

(defn process-rec [{tag :tag [x :as content] :content}]
  {tag (if (string? x) x (into {} (map process-rec) content))})

example:

user> (process-rec data)
;;=> {:Vehicle
;;    {:Model "Toyota",
;;     :Color "Red",
;;     :Loans {:Reoccuring "Monthly", :Owners {:Owner "Bob"}},
;;     :Tires {:Model "123123", :Size "23"},
;;     :Engine {:Model "30065"}}}
leetwinski
  • 17,408
  • 2
  • 18
  • 42