|
1 |
| -function M=json2mat(J) |
2 |
| -% JSON2MAT: converts a javscript data object (JSON) into a Matlab structure |
3 |
| -% using s recursive approach. J can also be a file name. |
4 |
| -% |
5 |
| -%Example: lala=json2mat('{lele:2,lili:4,lolo:[1,2,{lulu:5,bubu:[[1,2],[3,4],[5,6]]}]}') |
6 |
| -% notice lala.lolo{3}.bubu is read as a 2D matrix. |
7 |
| -% |
8 |
| -% Jonas Almeida, March 2010 |
9 |
| - |
10 |
| -if exist(J)==2 % if J is a filename |
11 |
| - fid=fopen(J,'r'); |
12 |
| - J=''; |
13 |
| - while ~feof(fid) |
14 |
| - J=[J,fgetl(fid)]; |
15 |
| - end |
16 |
| - fclose(fid); |
17 |
| - M=json2mat(J); |
18 |
| -else |
19 |
| - J1=regexprep(J(1:min([5,length(J)])),'\s',''); %despaced start of J string |
20 |
| - if J1(1)=='{' %extract structures |
21 |
| - JJ=regexp(J,'\{(.*)\}','tokens'); |
22 |
| - M=extract_struct(JJ{1}{1}); |
23 |
| - elseif J1(1)=='[' %extract cells |
24 |
| - JJ=regexp(J,'\[(.*)\]','tokens'); |
25 |
| - M=extract_cell(JJ{1}{1}); |
26 |
| - elseif J1(1)=='"' %literal string |
27 |
| - JJ=regexp(J,'\"(.*)\"','tokens'); |
28 |
| - M=JJ{1}{1}; |
29 |
| - else %numeric value |
30 |
| - M=str2num(J); % is number |
31 |
| - end |
32 |
| -end |
33 |
| - |
34 |
| -function y=extract_struct(x) |
35 |
| -%detag arrays first |
36 |
| -indOC=extract_embed(x,'[',']'); |
37 |
| -n=size(indOC,1); |
38 |
| -for i=n:-1:1 |
39 |
| - tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
40 |
| - x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; |
41 |
| -end |
42 |
| - |
43 |
| - |
44 |
| -a=regexp(x,'[^:,]+:[^,]+'); |
45 |
| -n=length(a); |
46 |
| -a=[a,length(x)+2]; |
47 |
| -for i=1:n |
48 |
| - s=x(a(i):a(i+1)-2); |
49 |
| - t=regexp(s,'([^:]+):(.+)','tokens'); |
50 |
| - %t{1}{1}(t{1}{1}==32)=[]; % remove blanks, maybe later do something fancier like replace with underscores |
51 |
| - t{1}{1}=strrep(t{1}{1},' ','_'); |
52 |
| - t{1}{1}=strrep(t{1}{1},'"',''); |
53 |
| - if t{1}{1}(1)=='_' %JSON allows for fieldnames starting with "_" |
54 |
| - t{1}{1}(1)=''; % this line will cause hard to track problems if the same object has 2 attributes with the same name but one of them starting with "_" |
55 |
| - end |
56 |
| - if regexp(t{1}{2},'tag{\d+}') |
57 |
| - y.(t{1}{1})=eval(t{1}{2}); |
58 |
| - else |
59 |
| - y.(t{1}{1})=json2mat(t{1}{2}); |
60 |
| - end |
61 |
| - %y.(t{1}{1})=json2mat(t{1}{2}); |
62 |
| -end |
63 |
| - |
64 |
| -function y=extract_cell(x) |
65 |
| - |
66 |
| -indOC=extract_embed(x,'{','}'); |
67 |
| -n=size(indOC,1); |
68 |
| -for i=n:-1:1 |
69 |
| - tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
70 |
| - x=[x(1:indOC(i,1)-1),'tag~<',num2str(i),'>~',x(indOC(i,2)+1:end)]; |
71 |
| -end |
72 |
| -indOC=extract_embed(x,'[',']'); |
73 |
| -m=size(indOC,1); |
74 |
| -for j=m:-1:1 |
75 |
| - i=n+j; |
76 |
| - tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
77 |
| - try;tag{i}=cell2mat(tag{i});end |
78 |
| - x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; |
79 |
| -end |
80 |
| -x=strrep(x,'~<','{'); |
81 |
| -x=strrep(x,'>~','}'); |
82 |
| -if exist('tag') %catching numeric content |
83 |
| - if isnumeric([tag{:}]) |
84 |
| - try |
85 |
| - y=eval(['[',strrep(x,'},','};'),']']); |
86 |
| - end |
87 |
| - end |
88 |
| -end |
89 |
| - |
90 |
| -if exist('y')~=1 |
91 |
| - y=eval(['{',strrep(x,'"',''''),'}']); |
92 |
| -end |
93 |
| - |
94 |
| -%look for embeded objects and arrays |
95 |
| - |
96 |
| -function y=extract_embed(x,tagOpen,tagClose) |
97 |
| - |
98 |
| -%EXTRACT_EMBED identifies embeded tagged segments |
99 |
| -%Example y=extract_embed(str,'[',']') |
100 |
| - |
101 |
| -indOpen=strfind(x,tagOpen)'; |
102 |
| -indOpen=[indOpen,ones(length(indOpen),1)]; |
103 |
| -indClose=strfind(x,tagClose)'; |
104 |
| -indClose=[indClose,-ones(length(indClose),1)]; |
105 |
| -indOpenClose=[indOpen;indClose]; |
106 |
| -[NULL,Ind]=sort(indOpenClose(:,1)); |
107 |
| -clear NULL; |
108 |
| -indOpenClose=indOpenClose(Ind,:); |
109 |
| -n=size(indOpenClose,1); |
110 |
| -for i=2:n % add one for open, take one for close |
111 |
| - indOpenClose(i,2)=indOpenClose(i-1,2)+indOpenClose(i,2); |
112 |
| -end |
113 |
| -i=0; |
114 |
| -op=0; %open |
115 |
| -while i<n |
116 |
| - i=i+1; |
117 |
| - if (indOpenClose(i,2)==1)*(op==0) |
118 |
| - op=1; |
119 |
| - elseif indOpenClose(i,2)==0 |
120 |
| - op=0; |
121 |
| - else |
122 |
| - indOpenClose(i,2)=-1; |
123 |
| - end |
124 |
| -end |
125 |
| -if isempty(indOpenClose) |
126 |
| - y=[]; |
127 |
| -else |
128 |
| - indOpenClose(indOpenClose(:,2)<0,:)=[]; |
129 |
| - y=[indOpenClose(1:2:end,1),indOpenClose(2:2:end,1)];% Open/Close Indexes |
130 |
| -end |
| 1 | +function M=json2mat(J) |
| 2 | +% JSON2MAT: converts a javscript data object (JSON) into a Matlab structure |
| 3 | +% using s recursive approach. J can also be a file name. |
| 4 | +% |
| 5 | +%Example: lala=json2mat('{lele:2,lili:4,lolo:[1,2,{lulu:5,bubu:[[1,2],[3,4],[5,6]]}]}') |
| 6 | +% notice lala.lolo{3}.bubu is read as a 2D matrix. |
| 7 | +% |
| 8 | +% Jonas Almeida, March 2010 |
| 9 | + |
| 10 | +if exist(J)==2 % if J is a filename |
| 11 | + fid=fopen(J,'r'); |
| 12 | + J=''; |
| 13 | + while ~feof(fid) |
| 14 | + J=[J,fgetl(fid)]; |
| 15 | + end |
| 16 | + fclose(fid); |
| 17 | + M=json2mat(J); |
| 18 | +else |
| 19 | + J1=regexprep(J(1:min([5,length(J)])),'\s',''); %despaced start of J string |
| 20 | + if J1(1)=='{' %extract structures |
| 21 | + JJ=regexp(J,'\{(.*)\}','tokens'); |
| 22 | + M=extract_struct(JJ{1}{1}); |
| 23 | + elseif J1(1)=='[' %extract cells |
| 24 | + JJ=regexp(J,'\[(.*)\]','tokens'); |
| 25 | + M=extract_cell(JJ{1}{1}); |
| 26 | + elseif J1(1)=='"' %literal string |
| 27 | + JJ=regexp(J,'\"(.*)\"','tokens'); |
| 28 | + % 2FIX: should convert all the 'crap' back: \" -> ", \b -> backspace, etc. |
| 29 | + M=JJ{1}{1}; |
| 30 | + else %numeric value |
| 31 | + M=str2num(J); % is number |
| 32 | + end |
| 33 | +end |
| 34 | + |
| 35 | +function y=extract_struct(x) |
| 36 | +%detag arrays first |
| 37 | +indOC=extract_embed(x,'[',']'); |
| 38 | +n=size(indOC,1); |
| 39 | +for i=n:-1:1 |
| 40 | + tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
| 41 | + x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; |
| 42 | +end |
| 43 | + |
| 44 | + |
| 45 | +a=regexp(x,'[^:,]+:[^,]+'); |
| 46 | +n=length(a); |
| 47 | +a=[a,length(x)+2]; |
| 48 | +for i=1:n |
| 49 | + s=x(a(i):a(i+1)-2); |
| 50 | + t=regexp(s,'([^:]+):(.+)','tokens'); |
| 51 | + %t{1}{1}(t{1}{1}==32)=[]; % remove blanks, maybe later do something fancier like replace with underscores |
| 52 | + t{1}{1}=strrep(t{1}{1},' ','_'); |
| 53 | + t{1}{1}=strrep(t{1}{1},'"',''); |
| 54 | + if t{1}{1}(1)=='_' %JSON allows for fieldnames starting with "_" |
| 55 | + t{1}{1}(1)=''; % this line will cause hard to track problems if the same object has 2 attributes with the same name but one of them starting with "_" |
| 56 | + end |
| 57 | + if regexp(t{1}{2},'tag{\d+}') |
| 58 | + y.(t{1}{1})=eval(t{1}{2}); |
| 59 | + else |
| 60 | + y.(t{1}{1})=json2mat(t{1}{2}); |
| 61 | + end |
| 62 | + %y.(t{1}{1})=json2mat(t{1}{2}); |
| 63 | +end |
| 64 | + |
| 65 | +function y=extract_cell(x) |
| 66 | + |
| 67 | +indOC=extract_embed(x,'{','}'); |
| 68 | +n=size(indOC,1); |
| 69 | +for i=n:-1:1 |
| 70 | + tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
| 71 | + x=[x(1:indOC(i,1)-1),'tag~<',num2str(i),'>~',x(indOC(i,2)+1:end)]; |
| 72 | +end |
| 73 | +indOC=extract_embed(x,'[',']'); |
| 74 | +m=size(indOC,1); |
| 75 | +for j=m:-1:1 |
| 76 | + i=n+j; |
| 77 | + tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); |
| 78 | + try;tag{i}=cell2mat(tag{i});end |
| 79 | + x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; |
| 80 | +end |
| 81 | +x=strrep(x,'~<','{'); |
| 82 | +x=strrep(x,'>~','}'); |
| 83 | +if exist('tag') %catching numeric content |
| 84 | + if isnumeric([tag{:}]) |
| 85 | + try |
| 86 | + y=eval(['[',strrep(x,'},','};'),']']); |
| 87 | + end |
| 88 | + end |
| 89 | +end |
| 90 | + |
| 91 | +if exist('y')~=1 |
| 92 | + y=eval(['{',strrep(x,'"',''''),'}']); |
| 93 | +end |
| 94 | + |
| 95 | +%look for embeded objects and arrays |
| 96 | + |
| 97 | +function y=extract_embed(x,tagOpen,tagClose) |
| 98 | + |
| 99 | +%EXTRACT_EMBED identifies embeded tagged segments |
| 100 | +%Example y=extract_embed(str,'[',']') |
| 101 | + |
| 102 | +indOpen=strfind(x,tagOpen)'; |
| 103 | +indOpen=[indOpen,ones(length(indOpen),1)]; |
| 104 | +indClose=strfind(x,tagClose)'; |
| 105 | +indClose=[indClose,-ones(length(indClose),1)]; |
| 106 | +indOpenClose=[indOpen;indClose]; |
| 107 | +[NULL,Ind]=sort(indOpenClose(:,1)); |
| 108 | +clear NULL; |
| 109 | +indOpenClose=indOpenClose(Ind,:); |
| 110 | +n=size(indOpenClose,1); |
| 111 | +for i=2:n % add one for open, take one for close |
| 112 | + indOpenClose(i,2)=indOpenClose(i-1,2)+indOpenClose(i,2); |
| 113 | +end |
| 114 | +i=0; |
| 115 | +op=0; %open |
| 116 | +while i<n |
| 117 | + i=i+1; |
| 118 | + if (indOpenClose(i,2)==1)*(op==0) |
| 119 | + op=1; |
| 120 | + elseif indOpenClose(i,2)==0 |
| 121 | + op=0; |
| 122 | + else |
| 123 | + indOpenClose(i,2)=-1; |
| 124 | + end |
| 125 | +end |
| 126 | +if isempty(indOpenClose) |
| 127 | + y=[]; |
| 128 | +else |
| 129 | + indOpenClose(indOpenClose(:,2)<0,:)=[]; |
| 130 | + y=[indOpenClose(1:2:end,1),indOpenClose(2:2:end,1)];% Open/Close Indexes |
| 131 | +end |
0 commit comments