Skip to content

Commit

Permalink
[bug] support deep scan in cell and struct, merge struct/containers.Map
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed Mar 21, 2024
1 parent 394394a commit c9f8a20
Showing 1 changed file with 28 additions and 32 deletions.
60 changes: 28 additions & 32 deletions jsonpath.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
%

obj = root;
jsonpath = regexprep(jsonpath, '([^.])(\[[0-9:]+\])', '$1.$2');
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)
Expand All @@ -45,13 +45,14 @@

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

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

if (strcmp(pathname, '$'))
obj = input;
elseif (regexp(pathname, '$\d+'))
obj = input(str2double(pathname(2:end)) + 1);
elseif (~isempty(regexp(pathname, '^\[[0-9:]+\]$', 'once')) || iscell(input))
elseif (~isempty(regexp(pathname, '^\[[0-9\*:]+\]$', 'once')) || iscell(input))
arraystr = pathname(2:end - 1);
if (find(arraystr == ':'))
[arraystr, arrayrange] = regexp(arraystr, '(\d*):(\d*)', 'match', 'tokens');
Expand All @@ -69,37 +70,51 @@
elseif (regexp(arraystr, '^[0-9:]+', 'once'))
arrayrange = str2double(arraystr) + 1;
arrayrange = {arrayrange, arrayrange};
end
if (~exist('arrayrange', 'var'))
elseif (~isempty(regexp(arraystr, '^\*', 'once')))
arrayrange = {1, length(input)};
end
if (iscell(input))
if (exist('arrayrange', 'var'))
obj = {input{arrayrange{1}:arrayrange{2}}};
else
arrayrange = {1, length(input)};
end
if (~exist('obj', 'var') && iscell(input))
input = {input{arrayrange{1}:arrayrange{2}}};
if (deepscan)
searchkey = ['..' pathname];
[val, isfound] = getonelevel(obj, [paths{1:pathid} {searchkey}], pathid + 1);
else
searchkey = origpath;
end
for idx = 1:length(input)
[val, isfound] = getonelevel(input{idx}, [paths{1:pathid - 1} {searchkey}], pathid);
if (isfound)
if (~exist('newobj', 'var'))
newobj = {};
end
newobj = [newobj(:)', {val}];
end
if (exist('newobj', 'var'))
obj = newobj;
end
end
if (exist('newobj', 'var'))
obj = newobj;
end
if (exist('obj', 'var') && iscell(obj) && length(obj) == 1)
obj = obj{1};
end
else
obj = input(arrayrange{1}:arrayrange{2});
end
elseif (isstruct(input))
elseif (isstruct(input) || isa(input, 'containers.Map'))
stpath = encodevarname(pathname);
if (deepscan)
if (isstruct(input))
if (isfield(input, stpath))
obj = {input.(stpath)};
end
else
if (isKey(input, pathname))
obj = {input(pathname)};
end
end
if (~exist('obj', 'var') && deepscan)
items = fieldnames(input);
for idx = 1:length(items)
[val, isfound] = getonelevel(input.(items{idx}), [paths{1:pathid - 1} {['..' pathname]}], pathid);
Expand All @@ -113,28 +128,9 @@
if (exist('obj', 'var') && length(obj) == 1)
obj = obj{1};
end
else
if (isfield(input, stpath))
obj = input.(stpath);
end
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}), [paths{:} {['..' pathname]}], pathid + 1);
if (isfound)
if (~exist('obj', 'var'))
obj = {};
end
obj = [obj{:}, val];
end
end
else
obj = input(pathname);
if (exist('obj', 'var') && iscell(obj) && length(obj) == 1)
obj = obj{1};
end
elseif (isa(input, 'table'))
obj = input(:, pathname);
Expand Down

0 comments on commit c9f8a20

Please sign in to comment.