Skip to content

Commit 4f2edeb

Browse files
committed
[feat] support .. jsonpath operator for deep scan
1 parent c43a758 commit 4f2edeb

File tree

2 files changed

+114
-23
lines changed

2 files changed

+114
-23
lines changed

getfromjsonpath.m

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,99 @@
2323
%
2424

2525
obj = root;
26-
jsonpath = regexprep(jsonpath, '([^.])(\[\d+\])', '$1.$2');
27-
[pat, paths] = regexp(jsonpath, '\.*([^\s\.]+)\.*', 'match', 'tokens');
26+
jsonpath = regexprep(jsonpath, '([^.])(\[[0-9:]+\])', '$1.$2');
27+
[pat, paths] = regexp(jsonpath, '(\.{0,2}[^\s\.]+)', 'match', 'tokens');
2828
if (~isempty(pat) && ~isempty(paths))
2929
for i = 1:length(paths)
30-
if (strcmp(paths{i}{1}, '$'))
31-
continue
32-
elseif (regexp(paths{i}{1}, '$\d+'))
33-
obj = obj(str2double(paths{i}{1}(2:end)) + 1);
34-
elseif (regexp(paths{i}{1}, '^\[\d+\]$'))
35-
if (iscell(obj))
36-
obj = obj{str2double(paths{i}{1}(2:end - 1)) + 1};
37-
else
38-
obj = obj(str2double(paths{i}{1}(2:end - 1)) + 1);
39-
end
40-
elseif (isstruct(obj))
41-
obj = obj.(encodevarname(paths{i}{1}));
42-
elseif (isa(obj, 'containers.Map'))
43-
obj = obj(paths{i}{1});
44-
elseif (isa(obj, 'table'))
45-
obj = obj(:, paths{i}{1});
30+
[obj, isfound] = getonelevel(obj, paths{i}{1});
31+
if (~isfound)
32+
return
33+
end
34+
end
35+
end
36+
37+
%% scan function
38+
39+
function [obj, isfound] = getonelevel(input, pathname)
40+
41+
deepscan = ~isempty(regexp(pathname, '^\.\.', 'once'));
42+
43+
pathname = regexprep(pathname, '^\.+', '');
44+
45+
if (strcmp(pathname, '$'))
46+
obj = input;
47+
elseif (regexp(pathname, '$\d+'))
48+
obj = input(str2double(pathname(2:end)) + 1);
49+
elseif (regexp(pathname, '^\[[0-9:]+\]$'))
50+
arraystr = pathname(2:end - 1);
51+
if (find(arraystr == ':'))
52+
[arraystr, arrayrange] = regexp(arraystr, '(\d*):(\d*)', 'match', 'tokens');
53+
arrayrange = arrayrange{1};
54+
if (~isempty(arrayrange{1}))
55+
arrayrange{1} = str2double(arrayrange{1}) + 1;
56+
else
57+
arrayrange{1} = 1;
58+
end
59+
if (~isempty(arrayrange{2}))
60+
arrayrange{2} = str2double(arrayrange{2}) + 1;
4661
else
47-
error('json path segment (%d) "%s" can not be found in the input object\n', i, paths{i}{1});
62+
arrayrange{2} = length(input);
4863
end
64+
else
65+
arrayrange = str2double(arraystr) + 1;
66+
arrayrange = {arrayrange, arrayrange};
4967
end
68+
if (iscell(input))
69+
obj = {input{arrayrange{1}:arrayrange{2}}};
70+
else
71+
obj = input(arrayrange{1}:arrayrange{2});
72+
end
73+
elseif (isstruct(input))
74+
stpath = encodevarname(pathname);
75+
if (deepscan)
76+
if (isfield(input, stpath))
77+
obj = {input.(stpath)};
78+
end
79+
items = fieldnames(input);
80+
for idx = 1:length(items)
81+
[val, isfound] = getonelevel(input.(items{idx}), ['..' pathname]);
82+
if (isfound)
83+
if (~exist('obj', 'var'))
84+
obj = {};
85+
end
86+
obj = [obj{:}, val];
87+
end
88+
end
89+
else
90+
obj = input.(stpath);
91+
end
92+
elseif (isa(input, 'containers.Map'))
93+
if (deepscan)
94+
if (isKey(input, pathname))
95+
obj = {input(pathname)};
96+
end
97+
items = keys(input);
98+
for idx = 1:length(items)
99+
[val, isfound] = getonelevel(input(items{idx}), ['..' pathname]);
100+
if (isfound)
101+
if (~exist('obj', 'var'))
102+
obj = {};
103+
end
104+
obj = [obj{:}, val];
105+
end
106+
end
107+
else
108+
obj = input(pathname);
109+
end
110+
elseif (isa(input, 'table'))
111+
obj = input(:, pathname);
112+
elseif (~deepscan)
113+
error('json path segment "%s" can not be found in the input object\n', pathname);
114+
end
115+
116+
if (~exist('obj', 'var'))
117+
isfound = false;
118+
obj = [];
119+
elseif (nargout > 1)
120+
isfound = true;
50121
end

loadjd.m

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
% *.bjd,.bnii,.jdb,.bmsh,.bnirs,.pmat: binary JData (BJData) files, see https://neurojson.org/bjdata/draft2
1717
% *.ubj: UBJSON-encoded files, see http://ubjson.org
1818
% *.msgpack: MessagePack-encoded files, see http://msgpack.org
19-
% *.h5,.hdf5,.snirf: HDF5 files, see https://www.hdfgroup.org/
19+
% *.h5,.hdf5,.snirf,.nwb: HDF5 files, see https://www.hdfgroup.org/
20+
% *.nii,.nii.gz: NIfTI files, need http://github.com/NeuroJSON/jnifty
21+
% *.tsv,.tsv.gz,.csv,.csv.gz: TSV/CSV files, need http://github.com/NeuroJSON/jbids
22+
% *.bval,.bvec: EEG .bval and .bvec files
23+
% *.mat: MATLAB/Octave .mat files
2024
% options: (optional) for JSON/JData files, these are optional 'param',value pairs
2125
% supported by loadjson.m; for BJData/UBJSON/MessagePack files, these are
2226
% options supported by loadbj.m; for HDF5 files, these are options
@@ -45,17 +49,33 @@
4549

4650
if (regexpi(filename, '\.json$|\.jnii$|\.jdt$|\.jdat$|\.jmsh$|\.jnirs|\.jbids$'))
4751
[varargout{1:nargout}] = loadjson(filename, varargin{:});
48-
elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat'))
52+
elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat$'))
4953
[varargout{1:nargout}] = loadbj(filename, varargin{:});
5054
elseif (regexpi(filename, '\.ubj$'))
5155
[varargout{1:nargout}] = loadubjson(filename, varargin{:});
5256
elseif (regexpi(filename, '\.msgpack$'))
5357
[varargout{1:nargout}] = loadmsgpack(filename, varargin{:});
54-
elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$'))
58+
elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$|\.nwb$'))
5559
if (~exist('loadh5', 'file'))
5660
error('you must first install EasyH5 from http://github.com/NeuroJSON/easyh5/');
5761
end
5862
[varargout{1:nargout}] = loadh5(filename, varargin{:});
63+
elseif (regexpi(filename, '\.nii$|\.nii\.gz$'))
64+
if (~exist('loadnifti', 'file'))
65+
error('you must first install JNIFTY toolbox from http://github.com/NeuroJSON/jnifty/');
66+
end
67+
[varargout{1:nargout}] = loadnifti(filename, varargin{:});
68+
elseif (regexpi(filename, '\.tsv$|\.tsv\.gz$|\.csv$|\.csv\.gz$'))
69+
if (~exist('loadbidstsv', 'file'))
70+
error('you must first install JBIDS toolbox from http://github.com/NeuroJSON/jbids/');
71+
end
72+
delim = sprintf('\t');
73+
if (regexpi(filename, '\.csv'))
74+
delim = ',';
75+
end
76+
[varargout{1:nargout}] = loadbidstsv(filename, delim);
77+
elseif (regexpi(filename, '\.mat$|\.bvec$|\.bval$'))
78+
[varargout{1:nargout}] = load(filename, varargin{:});
5979
else
60-
error('file suffix must be one of .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,.h5,.hdf5,.snirf,.pmat');
80+
error('file suffix must be one of .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,.h5,.hdf5,.snirf,.pmat,.nwb,.nii,.nii.gz,.tsv,.tsv.gz,.csv,.csv.gz,.mat,.bvec,.bval');
6181
end

0 commit comments

Comments
 (0)