4
$\begingroup$

I can't seem to find a way to convert between an XML string and RawJSON:

xml = "<root>
    <fair>
      <there>
        <fog>balloon</fog>
        <flew>load</flew>
        <slipped>pan</slipped>
        <shine>1616809877.197722</shine>
        <general>warm</general>
        <stock>pale</stock>
      </there>
      <higher>273906901</higher>
      <environment>673083878</environment>
      <raw>-1195497107</raw>
      <lunch>1930133836</lunch>
      <body>wool</body>
    </fair>
    <green>831388325</green>
    <writer>-465508588.16013575</writer>
    <chest>touch</chest>
    <score>-969560157</score>
    <aboard>-1575070350</aboard>
  </root>";
ixml = ImportString[xml, "XML"];
ExportString[ixml, "RawJSON"]

enter image description here

Must be a simple answer here...

$\endgroup$
6
$\begingroup$

It's not clear how XML can be converted to JSON in a general way, because how would one deal with attributes? You happen not to have attributes in your XML, but that's just a special case.

Luckily, Mathematica is a great language to write ad hoc parsers in.

convert[XMLObject["Document"][{}, content_, {}]] := convert[content]
convert[XMLElement[tagName_, _, children : {__XMLElement}]] := <|tagName -> convert /@ children|>
convert[XMLElement[tagName_, _, {child_}]] := <|tagName -> child|>
ExportString[convert[xml], "JSON"]

{ "root":[ { "fair":[ { "there":[ { "fog":"balloon" }, ...

| improve this answer | |
$\endgroup$
  • $\begingroup$ Sure but I thought some Developer` or Internal` function would to do this $\endgroup$ – M.R. Oct 18 '19 at 20:38
4
$\begingroup$

I've not been involved with XML lately, but I used to (re)define XMLObject and XMLElement to process an XML structure. It's usually received lukewarm appreciation on this site, but it seems like the sort of expression-rewriting Mathematica was built for. And in this case, it's easy:

json = Block[
   { XMLObject = Function[{#2} &],
   , XMLElement = #1 -> Replace[#3, {x_} :> x] &
   }
 , ixml
 ]
(*
{"root" -> {
   "fair" -> {
     "there" -> {
       "fog" -> "balloon",
       "flew" -> "load",
       "slipped" -> "pan",
       "shine" -> "1616809877.197722",
       "general" -> "warm",
       "stock" -> "pale"},
     "higher" -> "273906901",
     "environment" -> "673083878",
     "raw" -> "-1195497107",
     "lunch" -> "1930133836",
     "body" -> "wool"},
   "green" -> "831388325",
   "writer" -> "-465508588.16013575",
   "chest" -> "touch",
   "score" -> "-969560157",
   "aboard" -> "-1575070350"}}
*)

The above is converted to JSON with

ExportString[json, "JSON"]

If "RawJSON" is desired, convert the "JSON" string:

ExportString[ExportString[json, "JSON"], "RawJSON"]

Some consistency checks:

json === ImportString[ExportString[json, "JSON"], "JSON"]
(*  True  *)

json === ImportString[
  ImportString[ExportString[ExportString[json, "JSON"], "RawJSON"], 
   "RawJSON"], "JSON"]
(*  True  *)

ixml === (
  XMLObject["Document"][{}, #, {}] & @@ json /. 
   Rule -> (XMLElement[#1, {}, 
       Replace[#2, atom : Except[_List] :> {atom}]] &)
  )
(*  True  *)
| improve this answer | |
$\endgroup$
3
$\begingroup$

Perhaps you can pre-process your data before feeding it in Mathematica? If so, I'd suggest you consider Data Transformer (disclaimer - I'm its developer).

It offers a number of conversion settings (with sensible defaults) so you can match the data for your purposes. You can choose how to treat XM attributes, embedded text etc.

It's available on the Mac App Store and the Microsoft Store.

Here's Data Transformer's JSON output with the default settings for your example:

{
  "root": {
    "fair": {
      "there": {
        "fog": "balloon",
        "flew": "load",
        "slipped": "pan",
        "shine": 1616809877.197722,
        "general": "warm",
        "stock": "pale"
      },
      "higher": 273906901,
      "environment": 673083878,
      "raw": -1195497107,
      "lunch": 1930133836,
      "body": "wool"
    },
    "green": 831388325,
    "writer": -465508588.16013575,
    "chest": "touch",
    "score": -969560157,
    "aboard": -1575070350
  }
}
| improve this answer | |
$\endgroup$
  • 2
    $\begingroup$ The XML input is given. Can you show how it is converted to JSON? (See 2nd bullet point here: mathematica.stackexchange.com/help/promotion) $\endgroup$ – Michael E2 Jan 1 at 4:05
  • $\begingroup$ The app costs \$3 in the Mac App Store and \$5 in the MS store. (In case someone wants to test this answer....) $\endgroup$ – Anton Antonov Jan 1 at 16:07
  • $\begingroup$ Thank you. (+1). $\endgroup$ – Michael E2 Jan 1 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.