Skip to content

Commit

Permalink
[feat] support .. jsonpath operator for deep scan
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed Feb 20, 2024
1 parent c43a758 commit 4f2edeb
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 23 deletions.
109 changes: 90 additions & 19 deletions getfromjsonpath.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,99 @@
%

obj = root;
jsonpath = regexprep(jsonpath, '([^.])(\[\d+\])', '$1.$2');
[pat, paths] = regexp(jsonpath, '\.*([^\s\.]+)\.*', 'match', 'tokens');
jsonpath = regexprep(jsonpath, '([^.])(\[[0-9:]+\])', '$1.$2');
[pat, paths] = regexp(jsonpath, '(\.{0,2}[^\s\.]+)', 'match', 'tokens');
if (~isempty(pat) && ~isempty(paths))
for i = 1:length(paths)
if (strcmp(paths{i}{1}, '$'))
continue
elseif (regexp(paths{i}{1}, '$\d+'))
obj = obj(str2double(paths{i}{1}(2:end)) + 1);
elseif (regexp(paths{i}{1}, '^\[\d+\]$'))
if (iscell(obj))
obj = obj{str2double(paths{i}{1}(2:end - 1)) + 1};
else
obj = obj(str2double(paths{i}{1}(2:end - 1)) + 1);
end
elseif (isstruct(obj))
obj = obj.(encodevarname(paths{i}{1}));
elseif (isa(obj, 'containers.Map'))
obj = obj(paths{i}{1});
elseif (isa(obj, 'table'))
obj = obj(:, paths{i}{1});
[obj, isfound] = getonelevel(obj, paths{i}{1});
if (~isfound)
return
end
end
end

%% scan function

function [obj, isfound] = getonelevel(input, pathname)

deepscan = ~isempty(regexp(pathname, '^\.\.', 'once'));

pathname = regexprep(pathname, '^\.+', '');

if (strcmp(pathname, '$'))
obj = input;
elseif (regexp(pathname, '$\d+'))
obj = input(str2double(pathname(2:end)) + 1);
elseif (regexp(pathname, '^\[[0-9:]+\]$'))
arraystr = pathname(2:end - 1);
if (find(arraystr == ':'))
[arraystr, arrayrange] = regexp(arraystr, '(\d*):(\d*)', 'match', 'tokens');
arrayrange = arrayrange{1};
if (~isempty(arrayrange{1}))
arrayrange{1} = str2double(arrayrange{1}) + 1;
else
arrayrange{1} = 1;
end
if (~isempty(arrayrange{2}))
arrayrange{2} = str2double(arrayrange{2}) + 1;
else
error('json path segment (%d) "%s" can not be found in the input object\n', i, paths{i}{1});
arrayrange{2} = length(input);
end
else
arrayrange = str2double(arraystr) + 1;
arrayrange = {arrayrange, arrayrange};
end
if (iscell(input))
obj = {input{arrayrange{1}:arrayrange{2}}};
else
obj = input(arrayrange{1}:arrayrange{2});
end
elseif (isstruct(input))
stpath = encodevarname(pathname);
if (deepscan)
if (isfield(input, stpath))
obj = {input.(stpath)};
end
items = fieldnames(input);
for idx = 1:length(items)
[val, isfound] = getonelevel(input.(items{idx}), ['..' pathname]);
if (isfound)
if (~exist('obj', 'var'))
obj = {};
end
obj = [obj{:}, val];
end
end
else
obj = input.(stpath);
end
elseif (isa(input, 'containers.Map'))
if (deepscan)
if (isKey(input, pathname))
obj = {input(pathname)};
end
items = keys(input);
for idx = 1:length(items)
[val, isfound] = getonelevel(input(items{idx}), ['..' pathname]);
if (isfound)
if (~exist('obj', 'var'))
obj = {};
end
obj = [obj{:}, val];
end
end
else
obj = input(pathname);
end
elseif (isa(input, 'table'))
obj = input(:, pathname);
elseif (~deepscan)
error('json path segment "%s" can not be found in the input object\n', pathname);
end

if (~exist('obj', 'var'))
isfound = false;
obj = [];
elseif (nargout > 1)
isfound = true;
end
28 changes: 24 additions & 4 deletions loadjd.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
% *.bjd,.bnii,.jdb,.bmsh,.bnirs,.pmat: binary JData (BJData) files, see https://neurojson.org/bjdata/draft2
% *.ubj: UBJSON-encoded files, see http://ubjson.org
% *.msgpack: MessagePack-encoded files, see http://msgpack.org
% *.h5,.hdf5,.snirf: HDF5 files, see https://www.hdfgroup.org/
% *.h5,.hdf5,.snirf,.nwb: HDF5 files, see https://www.hdfgroup.org/
% *.nii,.nii.gz: NIfTI files, need http://github.com/NeuroJSON/jnifty
% *.tsv,.tsv.gz,.csv,.csv.gz: TSV/CSV files, need http://github.com/NeuroJSON/jbids
% *.bval,.bvec: EEG .bval and .bvec files
% *.mat: MATLAB/Octave .mat files
% options: (optional) for JSON/JData files, these are optional 'param',value pairs
% supported by loadjson.m; for BJData/UBJSON/MessagePack files, these are
% options supported by loadbj.m; for HDF5 files, these are options
Expand Down Expand Up @@ -45,17 +49,33 @@

if (regexpi(filename, '\.json$|\.jnii$|\.jdt$|\.jdat$|\.jmsh$|\.jnirs|\.jbids$'))
[varargout{1:nargout}] = loadjson(filename, varargin{:});
elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat'))
elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat$'))
[varargout{1:nargout}] = loadbj(filename, varargin{:});
elseif (regexpi(filename, '\.ubj$'))
[varargout{1:nargout}] = loadubjson(filename, varargin{:});
elseif (regexpi(filename, '\.msgpack$'))
[varargout{1:nargout}] = loadmsgpack(filename, varargin{:});
elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$'))
elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$|\.nwb$'))
if (~exist('loadh5', 'file'))
error('you must first install EasyH5 from http://github.com/NeuroJSON/easyh5/');
end
[varargout{1:nargout}] = loadh5(filename, varargin{:});
elseif (regexpi(filename, '\.nii$|\.nii\.gz$'))
if (~exist('loadnifti', 'file'))
error('you must first install JNIFTY toolbox from http://github.com/NeuroJSON/jnifty/');
end
[varargout{1:nargout}] = loadnifti(filename, varargin{:});
elseif (regexpi(filename, '\.tsv$|\.tsv\.gz$|\.csv$|\.csv\.gz$'))
if (~exist('loadbidstsv', 'file'))
error('you must first install JBIDS toolbox from http://github.com/NeuroJSON/jbids/');
end
delim = sprintf('\t');
if (regexpi(filename, '\.csv'))
delim = ',';
end
[varargout{1:nargout}] = loadbidstsv(filename, delim);
elseif (regexpi(filename, '\.mat$|\.bvec$|\.bval$'))
[varargout{1:nargout}] = load(filename, varargin{:});
else
error('file suffix must be one of .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,.h5,.hdf5,.snirf,.pmat');
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');
end

0 comments on commit 4f2edeb

Please sign in to comment.