This function parses JSON strings. It converts JSON arrays into cell arrays and JSON objects into structures.
It is similar to the JSON parser by Joel Feenstra but often faster because of a better handling of strings.
1.4.0.0 | Updated description to take into account remark by Benjamin Ting |
|
1.2.0.0 | Contains previous update that was incorrectly uploaded |
|
1.1.0.0 | If needed, fields names are modified to make them compatible with MATLAB's requirements (only letters, digits and underscores, first character is a letter) |
Inspired by: JSON Parser
Inspired: JSONLab, skychart, Google(R) Translate, Highly portable JSON-input parser, JSONlab: a toolbox to encode/decode JSON files
Create scripts with code, output, and formatted text in a single executable document.
Lionel Trébuchon (view profile)
One of the greatest tools I have come across. Thanks!
I have one question though about line 51.
What explains the use of
cell(0, 1)
instead of
cell(0, 0)
? I think that cell(0,0) makes more sense to enable the possibility of creating a "real" empty MATLAB cell through the use of "[]" in JSON.
d_moan (view profile)
great work. loved the use of nested functions.
I had an error generated from the implementation of parse_number because of the line
[num, one, err, delta] = sscanf(string(pos:min(len,pos+20)), '%f', 1);
the number read was longer than 20 digits, and so when the time came to parse_char(',') , a digit was read instead and an error was thrown.
I saw in the comments you considered using pos:end, but that was x3 slower, just in that area of the json.
my proposed solution:
define in the beginning:
not_nums = regexp(string, '[^\d.eE+\-()[]]'); % nothing more comoplicated is needed as we're interested in the maximal length, so "false positives" will have no significat effect
if isempty(not_nums), not_nums = 0; end
max_num_len = max(max(diff(not_nums)),20);
and use max_num_len instead of 20 in parse_number
Kevin Cheng (view profile)
d_moan (view profile)
getkan woson (view profile)
FYI Qianqian Fang, JSONLab was up to 4x slower than this for files in the 200kB range
soo.. this is great, thx!
Brendan Hannigan (view profile)
fast!
jason (view profile)
hello Francois! I have used your program to parse my json file and it succeeded! thank your for your efforts!
but when I try to use parse_json to parse a much larger json file which is 3.38G errors occurred. I can't understand the errors, can you help me? follow is the error message:
Error using parse_json/error_pos (line 191)
Expected , at position 285210628 : ... " : "闂佃10璺?,
"<error>BaiduLongitute" : 121 ...
Error in parse_json/parse_char (line 68)
error_pos(sprintf('Expected %c at position %%d', c));
Error in parse_json/parse_object (line 43)
parse_char(',');
Error in parse_json/parse_value (line 157)
val = parse_object;
Error in parse_json/parse_array (line 54)
val = parse_value;
Error in parse_json (line 22)
data = parse_array;
Error in ProgrameForBus_position (line 2)
data=parse_json(string)
and I firstly use fileread function to transfer json to string, the string had been successfully obtained.
ciao (view profile)
Hi! I parsed this url:
url = 'http://api.wunderground.com/api/ea9003517a31d389/hourly10day/settings/q/IT/Venezia.json';
contents = urlread(url);
data = parse_json(contents);
How can I transform the structure data in arrays with the ourly temperature/humidity ext data?
Thanks in advance
davide
Oscar (view profile)
This worked great. (better than the original parser by Feenstra)
François Glineur (view profile)
Hi Karamos,
This code is designed to parse JSON strings ; in your example it is not clear where the JSON string to be parsed is supposed to come from. Also note this code should be called with a string, so "cellstr" is not necessary.
Karamos (view profile)
Could you please give me an indication how to convert this string into cell:
fullURL = ['http://www.fxstreet.com/'];
matlab_results = parse_json(cellstr(urlread(fullURL)))
I have the following error
??? SWITCH expression must be a scalar or string constant.
Error in ==> parse_json_V1 at 18
switch(next_char)
thanks
Qianqian Fang (view profile)
FYI, an optimized JSON parser, JSONlab, based on this work is available at
http://www.mathworks.com/matlabcentral/fileexchange/33381
It is 10x to 100x faster. A JSON encoder is also provided in JSONlab.
Jim Hokanson (view profile)
I love the use of nested functions! Well written.
Jim Hokanson (view profile)
Eric (view profile)
Works like a charm on WeatherBug REST JSON API output of hourly weather forecasts.
François Glineur (view profile)
Dear Benjamin: you are right, the function returns a cell array only if the topmost entity in the JSON string is an array ; if it is instead an object, the function returns a structure. I have updated the description to reflect that.
Benjamin Ting (view profile)
The comment box indicates the function returns a cell array. However, the return type is not a cell.
Thomas Smith (view profile)
Hi, does anyone know if there's a matlab script to *generate* JSON? It would be great if I could do both input and output... Otherwise I might have to use XML
naini naveen (view profile)
thanks again
Rob Newman (view profile)
François, I just downloaded the latest version and the problem still persists. Also, the file change time for parse_json.m is May 19, 2009 which is the same as the original (I think).
Rob Newman (view profile)
And thanks again!
Rob Newman (view profile)
I mean a real limitation in Matlab - NOT your script :)
François Glineur (view profile)
Rob, the problem is caused by field "526A", which MATLAB cannot accept because field names in MATLAB must start with a letter. I will update the parser to convert invalid field names into acceptable ones.
Rob Newman (view profile)
Thanks François - that helped! I was using fopen() and fread(). The fileread() function worked, to a point. Now I get an error:
??? Invalid field name: '526A'.
Error in ==> parse_json>parse_object at 39
object.(str) = val;
Here is a snippet of my JSON file, which does validate, as noted above:
{
"active":{
"E25A": {
"commtype":"cell modem",
"snet":"TA",
"provider":"verizon"
},
"TIGA":{
"commtype":"cell modem",
"snet":"TA",
"provider":"verizon"
},
"526A":{
"commtype":"cell modem",
"snet":"TA",
"provider":"verizon"
}
}
}
Note that the JSON file in its entirety is 200KB, so maybe there is an issue with how large a file your script can handle? Or possibly how 'deep' the object (i.e. how many levels of '{}') in the JSON structure there is?
François Glineur (view profile)
Rob, have you checked that the argument you pass to parse_json is a string ? The easiest way to convert the contents of a file into a string is to use the function fileread, as in this example :
s = fileread('file.json');
res = parse_json(s);
Rob Newman (view profile)
I have a JSON file local to my Matlab script. I fopen() and fread() the JSON file, but (another) JSON Parser crashes with the following error:
??? Undefined function or method 'regexp' for input arguments of type 'double'.
Error in ==> parse_json at 15
esc = regexp(string, '["\\]'); index_esc = 1; len_esc = length(esc);
Error in ==> ta_data_return at 35
file_sta_list = parse_json( json_file_obj ) ;
I checked the validity of the JSON source file at http://www.jsonlint.com/ and it is valid. Any ideas? Thanks in advance.
Michael Katz (view profile)
Good program, I made use of it in my google translate tool: http://www.mathworks.com/matlabcentral/fileexchange/23988
(i forgot to include the file in my first submission)
Patrick Boert (view profile)
Patrick Boert (view profile)
Thanks a lot François, this is exactly what I was looking for.
Joel Feenstra (view profile)
It is definitely faster than my version.