JSON
Formatted documentation for the JSON function.
Contents
Description
This was implemented using the
ECMA JSON syntax standard.
The failing and passing cases were validated using the test cases from a JSON test suite on
GitHub, containing over 300 cases of possibly
ambiguous syntax. Because the standard is not explicit for every situation, there are also test
cases left to the interpreter.
Implementation details for compatibility with the jsondecode Matlab function:
 If possible an array of arrays is treated as a rowmajor matrix.
 all data types should match
 all elements must be vectors of the same size
 The null literal is an empty double, unless it is an element of an array, in which case it is parsed as a NaN.
 The name of an object is converted to a valid field name with a function similar to genvarname or matlab.lang.makeValidName. This means characters after some whitespace characters are converted to uppercase, all whitespace is removed, invalid characters are replaced by an underscore, and an x is used as a prefix if the resulting name is empty or starts with a number or underscore. In case of duplicate object names, an underscore and a counter is added. A char(0) will cause the name to be cropped.
 An empty array ('[]') is encoded as an empty double (val=[]).
 An empty array array of arrays ('[[]]') is encoded as an empty cell (val={[]}).
Syntax
object=JSON(str) object=JSON(___,options) object=JSON(___,Name,Value) [object,ME]=JSON(___)
Output arguments
object  This contains the parsed object. This should closely match the output of the Matlab builtin jsondecode (see description). 
ME  Errors during parsing will be caught. If a second output argument is specified, the error will not be rethrown, but the corresponding MException object is returned instead. 
Input arguments
str  The JSON string to be parsed. This should be a char vector or a string/cellstr. 
Name,Value  The settings below can be entered with a Name,Value syntax. 
options  Instead of the Name,Value, parameters can also be entered in a struct. Missing fields will be set to the default values. 
Name,Value pairs
EnforceValidNumber 
With this boolean you can turn off the check if a number conforms to the JSON specifications.
This will cause str2double to determine the validity. No error will be thrown in case
of NaN output.
default=true; 
ThrowErrorForInvalid 
If this is false, no error will be throw if parsing fails. Instead, an empty array
is returned.
default=nargout<2; 
MaxRecursionDepth 
This function is a recursive function. Under some rare conditions, Matlab/Octave might crash when
the maximum recursion depth is reached, instead of throwing an error. This parameter allows you
to stay on the safe side.
The value can be set to inf to effectively remove the limit and only rely on the builtin safeguards. default=101numel(dbstack); 
Compatibility, version info, and licence
Compatibility considerations:
 The recursion depth is limited to 100. This will affect all combinations of nesting of arrays and objects. Without this, the recursion limit may be reached, causing Matlab/Octave to crash. Matlab/Octave should prevent this on their own, but this is in place in case that protection fails. The value can be set to inf to effectively remove the limit and only rely on the builtin safeguards.
Test suite result  Windows XP/7/10  Ubuntu 20.04 LTS  MacOS 10.15 Catalina 
Matlab R2021a  W10 : Pass  Pass  
Matlab R2020b  W10 : Pass  
Matlab R2020a  W10 : Pass  
Matlab R2018a  W10 : Pass  Pass  
Matlab R2017b  W10 : Pass  
Matlab R2017a  W7 : Pass  
Matlab R2016a  W10 : Pass  
Matlab R2015a  W10 : Pass  Pass  
Matlab R2013b  W10 : Pass  
Matlab R2012b  W10 : Pass  
Matlab R2011a  W10 : Pass  Pass  
Matlab R2010b  Pass  
Matlab R2010a  W7 : Pass  
Matlab R2007b  W10 : Pass  
Matlab 7.1 (R14SP3)  XP : Pass  
Matlab 6.5 (R13)  W10 : Pass  
Octave 6.2.0  W10 : Pass  
Octave 5.2.0  W10 : Pass  Pass  
Octave 4.4.1  W10 : Pass  Pass 
Version: 1.0.0 Date: 20210709 Author: H.J. Wisselink Licence: CC byncsa 4.0 ( https://creativecommons.org/licenses/byncsa/4.0 ) Email = 'h_j_wisselink*alumnus_utwente_nl'; Real_email = regexprep(Email,{'*','_'},{'@','.'})
Performance
The benchmarking function used to generate the results below can be found
here.
The test results shown in the tables below are normalized to the results of the newest
Matlab release on Windows, since the performace is strongly dependent on the specific
computer running the test. To allow absolute comparisons as well the results in that cell
are shown in seconds.
Note that every result apart from those under Windows 10 was obtained in a VM, so the
performance is likely an underestimation of the true performance.
Test 1: This test parses the citm_catalog.json file. The original file can be found on GitHub.
For this test the Matlab builtin (i.e. the jsondecode function) is 14 183 % slower. Note that the exact percentage depends on the exact system, Matlab version, and JSON file.
Test 2: Run the tests from the JSON Test Suite on GitHub. Note that the two largest tests are excluded. These tests have been preparsed to a struct array and converted to JSON so it could be easily included in this mfile.
The test comprises 317 cases. There are 95 cases that should pass, 188 cases that should fail, and 34 cases that are left to the interpreter (as there is no consensus on whether they are valid JSON or not).
For this test the Matlab builtin (i.e. the jsondecode function) is 46 % slower. Note that the exact percentage depends on the exact system, Matlab version, and JSON file.
Test suite result  Windows XP/7/10  Ubuntu 20.04 LTS  MacOS 10.15 Catalina 
Matlab R2021a  (W10) 6.984 s 0.305 s 
95 % 83 % 

Matlab R2020b  (W10) 101 % 98 % 

Matlab R2020a  (W10) 113 % 101 % 

Matlab R2018a  (W10) 136 % 95 % 
121 % 77 % 

Matlab R2017b  (W10) 144 % 96 % 

Matlab R2017a  (W7) 129 % 87 % 

Matlab R2016a  (W10) 144 % 103 % 

Matlab R2015a  (W10) 172 % 147 % 
179 % 130 % 

Matlab R2013b  (W10) 167 % 139 % 

Matlab R2012b  (W10) 223 % 142 % 

Matlab R2011a  (W10) 168 % 128 % 
175 % 109 % 

Matlab R2010b  168 % 102 % 

Matlab R2010a  (W7) 190 % 112 % 

Matlab R2007b  (W10) 155 % 92 % 

Matlab 7.1 (R14SP3)  (XP) 127 % 72 % 

Matlab 6.5 (R13)  (W10) 195 % 3 136 % 

Octave 6.2.0  (W10) 489 % 565 % 

Octave 5.2.0  (W10) 268 % 399 % 
197 % 292 % 

Octave 4.4.1  (W10) 255 % 410 % 
425 % 621 % 
Test suite
This tester is included so you can test if your own modifications would introduce any bugs. These tests form the basis for the compatibility table above.
Note that some of the functions in this tester might be different from the functions included in the actual function. Usually this is done to allow triggering of certain errors.
Even without comments or blank lines and compressing the functions down as much as possible, the tester function is too large for this page. The full tester function (including all comments) can be found here.