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$

3 Answers 3

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" }, ...

$\endgroup$
1
  • $\begingroup$ Sure but I thought some Developer` or Internal` function would to do this $\endgroup$
    – M.R.
    Oct 18, 2019 at 20:38
5
$\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  *)
$\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
  }
}
$\endgroup$
3
  • 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, 2020 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$ Jan 1, 2020 at 16:07
  • $\begingroup$ Thank you. (+1). $\endgroup$
    – Michael E2
    Jan 1, 2020 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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