Skip to content

Commit 0a582fb

Browse files
committed
[doc] add documentations for jsonpath, jsoncache, jdlink, and maxlinklevel
1 parent 5dba1de commit 0a582fb

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

README.rst

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ loadjson.m
487487
% request loadjson to store the data in a containers.Map instead of struct (key name limited to 63)
488488
dat=loadjson('{"obj":{"an object with a key longer than 63":"value","array":[1,2,3]}}', 'UseMap', 1)
489489
490+
% loadjson can further download the linked data pointed by _DataLink_ tag, and merge with the parent
491+
dat=loadjson('{"obj":{"_DataLink_":"https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json"},"array":[1,2]}','maxlinklevel',1)
492+
493+
% a JSONPath can be attached to the URL to retrieve a sub element
494+
dat=loadjson('{"obj":{"_DataLink_":"https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json:$.address.city"},"array":[1,2]}','maxlinklevel',1)
495+
490496
% loadjson can optionally return a JSON-memory-map object, which defines each JSON element's
491497
% memory buffer offset and length to enable disk-map like fast read/write operations
492498
[dat, mmap]=loadjson('{"obj":{"key":"value","array":[1,2,3]}}')
@@ -507,6 +513,9 @@ savebj.m
507513
% customizing the root-name using the 1st input, and the 3rd input setting the output file
508514
savebj('rootname',a,'testdata.ubj')
509515
516+
% enabling the 'debug' flag to allow printing binary JSON in text-form, helping users to run tests or troubleshoot
517+
savebj('rootname',a, 'debug',1)
518+
510519
% like savejson, savebj also allow data compression for even more compact storage
511520
savebj('zeros',zeros(100),'Compression','gzip')
512521
@@ -676,6 +685,112 @@ jsonset.m
676685
mmap = loadjson('/path/to/data.json', 'mmaponly', 1);
677686
jsonset('/path/to/data.json', mmap, '$.obj.string', '"new"', '$.obj.array', '[]')
678687
688+
----------
689+
jsonpath.m
690+
----------
691+
692+
.. code-block::
693+
694+
% JSONPath is a widely supported standard to index/search a large struct, such as those loaded from a JSON file
695+
% the jsonpath.m function implements a subset of the features
696+
% the below command returns the value of obj.key subfield, which is "value"
697+
obj = loadjson('{"obj":{"key":"value1","array":[1,2,3],"sub":{"key":"value2","array":[]}}}');
698+
jsonpath(obj, '$.obj.key')
699+
700+
% using [] operator, one can also index array elements, index start from 0; the output below is 2
701+
jsonpath(obj, '$.obj.array[1]')
702+
703+
% [] operator supports range, for example below commands yields [1,2]
704+
jsonpath(obj, '$.obj.array[0:1]')
705+
706+
% a negative index in [] counting elements backwards, -1 means the last element
707+
jsonpath(obj, '$.obj.array[-1]')
708+
709+
% jsonpath.m supports JSONPath's deep-scan operator '..', it traverses through the struct
710+
% and find all keys following .., here the output is {"value1", "value2"}
711+
jsonpath(obj, '$.obj..key')
712+
713+
% you can further concatenate JSONPath operators to select outputs from the earlier ones, this outputs {'value2'}
714+
jsonpath(obj, '$.obj..key[1]')
715+
716+
% instead of .keyname, you can use [keyname], below command is the same as above
717+
jsonpath(obj, '$[obj]..[key][1]')
718+
719+
% one can escape special char, such as ".", in the key using special\.key or [special.key]
720+
jsonpath(obj, '$.obj.special\.key.sub')
721+
722+
723+
-----------
724+
jsoncache.m
725+
-----------
726+
727+
.. code-block::
728+
729+
% the _DataLink_ annotation in the JData specification permits linking of external data files
730+
% in a JSON file - to make downloading/parsing externally linked data files efficient, such as
731+
% processing large neuroimaging datasets hosted on http://neurojson.io, we have developed a system
732+
% to download files on-demand and cache those locally. jsoncache.m is responsible of searching
733+
% the local cache folders, if found the requested file, it returns the path to the local cache;
734+
% if not found, it returns a SHA-256 hash of the URL as the file name, and the possible cache folders
735+
%
736+
% When loading a file from URL, below is the order of cache file search paths, ranking in search order
737+
%
738+
% global-variable NEUROJSON_CACHE | if defined, this path will be searched first
739+
% [pwd '/.neurojson'] | on all OSes
740+
% /home/USERNAME/.neurojson | on all OSes (per-user)
741+
% /home/USERNAME/.cache/neurojson | if on Linux (per-user)
742+
% /var/cache/neurojson | if on Linux (system wide)
743+
% /home/USERNAME/Library/neurojson| if on MacOS (per-user)
744+
% /Library/neurojson | if on MacOS (system wide)
745+
% C:\ProgramData\neurojson | if on Windows (system wide)
746+
%
747+
% When saving a file from a URL, under the root cache folder, subfolders can be created;
748+
% if the URL is one of a standard NeuroJSON.io URLs as below
749+
%
750+
% https://neurojson.org/io/stat.cgi?action=get&db=DBNAME&doc=DOCNAME&file=sub-01/anat/datafile.nii.gz
751+
% https://neurojson.io:7777/DBNAME/DOCNAME
752+
% https://neurojson.io:7777/DBNAME/DOCNAME/datafile.suffix
753+
%
754+
% the file datafile.nii.gz will be downloaded to /home/USERNAME/.neurojson/io/DBNAME/DOCNAME/sub-01/anat/ folder
755+
% if a URL does not follow the neurojson.io format, the cache folder has the below form
756+
%
757+
% CACHEFOLDER{i}/domainname.com/XX/YY/XXYYZZZZ...
758+
%
759+
% where XXYYZZZZ.. is the SHA-256 hash of the full URL, XX is the first two digit, YY is the 3-4 digits
760+
761+
% below command searches CACHEFOLDER{i}/io/openneuro/ds000001/sub-01/anat/, and return the path/filename
762+
[cachepath, filename] = jsoncache('https://neurojson.org/io/stat.cgi?action=get&db=openneuro&doc=ds000001&file=sub-01/anat/sub-01_inplaneT2.nii.gz&size=669578')
763+
764+
% this searches CACHEFOLDER{i}/raw.githubusercontent.com/55/d2, and the filename is 55d24a4bad6ecc3f5dc4d333be728e01c26b696ef7bc5dd0861b7fa672a28e8e.json
765+
[cachepath, filename] = jsoncache('https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json')
766+
767+
% this searches cachefolder{i}/io/adhd200/Brown folder, and look for file Brown.json
768+
[cachepath, filename] = jsoncache('https://neurojson.io:7777/adhd200/Brown')
769+
770+
% this searches cachefolder{i}/io/openneuro/ds003805 folder, and look for file ds003805.json
771+
[cachepath, filename] = jsoncache('https://neurojson.io:7777/openneuro/ds003805')
772+
773+
-----------
774+
jdlink.m
775+
-----------
776+
777+
.. code-block::
778+
779+
% jdlink dynamically downloads, caches and parses data files from one or multiple URLs
780+
% jdlink calls jsoncache to scan cache folders first, if a cache copy exists, it loads the cache first
781+
782+
% here we download a dataset from NeuroJSON.io, containing many linked data files
783+
data = loadjson('https://neurojson.io:7777/openneuro/ds000001');
784+
785+
% we now use jsonpath to scan all linked resources under subfolder "anat"
786+
alllinks = jsonpath(data, '$..anat.._DataLink_')
787+
788+
% let's download all linked nifti files (total 4) for sub-01 and sub-02, and load the files as niidata
789+
niidata = jdlink(alllinks, 'regex', 'sub-0[12]_.*\.nii');
790+
791+
% if you just want to download/cache all files and do not want to parse the files, you can run
792+
jdlink(alllinks);
793+
679794
---------
680795
examples
681796
---------

0 commit comments

Comments
 (0)