10
$\begingroup$

For creating non-empty object, I use following syntax

ExportString[{"key" -> "value"}, "JSON"]
(*{"key" : "value"}*)

But how can I create an empty object? When I run

ExportString[{}, "JSON"]
(*[]*)

it produces an empty array

PS: the empty object in JSON is {}

$\endgroup$
3
  • 1
    $\begingroup$ I think your question is answered here $\endgroup$
    – m_goldberg
    Jun 13, 2014 at 15:54
  • 1
    $\begingroup$ If you're having trouble, you could use If and export {} as a string {}. Just mentioning it because I think it's fairly common to have to treat special cases like this yourself in MMA. $\endgroup$
    – C. E.
    Jun 13, 2014 at 17:58
  • 2
    $\begingroup$ Here MMA assumes {} means a list of something (= []) unless it finds Rules in it. $\endgroup$
    – mfvonh
    Jun 14, 2014 at 2:42

2 Answers 2

11
$\begingroup$

You can define your own object and tell Mathematica to interpret it as JSON object.

Dummy export to load relevant contexts:

In[1]:= ExportString["", "JSON"];

Tell Mathematica to interpret JSONObject symbol as possible head of JSON objects:

In[2]:= ClearAll[JSONObject]
         System`Convert`JSONDump`$JSONObjectHead = JSONObject;

Now you can use JSONObject anywhere in exported expression:

In[4]:= ExportString[JSONObject[], "JSON"]
Out[4]= {}

In[5]:= ExportString[{"a" -> JSONObject[]}, "JSON"]
Out[5]= {"a" : {}}

In[6]:= ExportString[JSONObject["a" -> JSONObject["b" -> Null]], "JSON"]
Out[6]= {"a" : {"b" : null}}

How it works

Internally export to JSON is handled by System`Convert`JSONDump`exportJSON function which is just a wrapper for System`Convert`JSONDump`iexportJSON. The latter calls System`Convert`JSONDump`toString which does the real conversion and, among others, includes following definitions (System`Convert`JSONDump` context removed from symbol names):

toString[x_?($JSONObjectHead =!= List && MatchQ[#1, $JSONObjectHead[]]&), `t_Integer] := {}

toString[x_?($JSONObjectHead =!= List && Head[#1] === $JSONObjectHead && Length[#1] =!= 0&), t_Integer] := toString[List @@ x, t]

that use $JSONObjectHead.

How to find out, how exporting works

You can start by tracing evaluation of export expression:

TracePrint[
    ExportString["mySpecialString", "JSON"],
    _[___, "mySpecialString", ___]
]

You'll find that System`Convert`JSONDump` context looks interesting. For fast overview of it's symbols you can look at:

Names["System`Convert`JSONDump`*"] // TableForm

Real fun will start if you use this great spelunking tool:

Get["https://raw.githubusercontent.com/szhorvat/Spelunking/master/Spelunking.m"]

Pick a function, from printed trace that looks promising:

Spelunk["System`Convert`JSONDump`exportJSON"]

and dig deeper by clicking on links to functions that you see in the trace.

About spelunking tool I learned from one of halirutans answers.

$\endgroup$
3
  • $\begingroup$ nice, good answer. Thank you. $\endgroup$ Jun 16, 2014 at 7:18
  • $\begingroup$ were you found information about System`Convert`JSONDump`* function and variables? $\endgroup$ Jun 17, 2014 at 13:29
  • $\begingroup$ @molekyla777 I've expanded my answer. $\endgroup$
    – jkuczm
    Jun 18, 2014 at 7:02
7
$\begingroup$

For newer versions exporting an empty Association does what you want:

ExportString[<||>, "JSON"]

Newer Versions means >= 10.1, 10.0.x versions did export empty Associations to empty lists, of course the new behavior is a much better match for the distinction of JavaScript empty lists and objects in Mathematica...

As mentioned by Kuba in a comment the export format "JSON" has some deficiancies which are overcome by the export format "RawJSON" which seem to work better than "JSON" in many respects, especially when working with Associations...

Kubas example where "JSON" gives an error while "RawJSON" works as intendes was:

ExportString[<|"test" -> <||>|>, "RawJSON"]
$\endgroup$
0

Your Answer

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

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