gazpachoking/jsonref

How would references to schema elements in multiple files work?

Closed this issue ยท 4 comments

Could someone please provide a working example where there are references to several different files within a single json schema that's used in validation?

Many thanks!

I know this issue is open for more than one year now, but I recently also searched for a way to do this.
I found out that you can pass a base_uri to the parser so it has a path where it looks for the other files if referenced relatively.
It internally works with URLs (which start with the file:// schema tag), not simple file paths like /etc/my/example/config.json. Therefore it's not going to work if a string like the second one is passed as a base_uri.

Example (Python 3.4+):

from pathlib import Path
from urllib.parse import urljoin
from urllib.request import urlopen
import jsonref

# pathlib does not append trailing slashes, but jsonref needs that.
base_dir_url = Path('/absolute/path/to/base/dir').as_uri() + '/'
base_file_url = urljoin(base_dir_url, 'index.json')
base_file_content = urlopen(base_file_url).read().decode('utf-8')
json_object = jsonref.loads(base_file_content, base_uri=base_file_url)

The corresponding JSON files are structured as follows:

/absolute/path/to/base/dir/
    /subdir
        second.json
    first.json
    index.json

References inside index.json can look like this:

{
    "$ref": "file:./first.json"
}

... or when referencing something else than the root object/array of first.json from second.json:

{
    "$ref": "file:../first.json#/some/subobject"
}

Note that paths starting with #/ are always local to the file and need to be prefixed with file: paths when outside the current file.

I know this is even older now, but to add you can also do this without the file: bit in the reference.

aaa@aaa:~/work/gazpachoking-jsonref$ cat test.json 
{
	"cat":"woof"
}

aaa@aaa:~/work/gazpachoking-jsonref$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pprint import pprint
>>> import jsonref
>>> from pathlib import Path
>>> import os 
>>> from urllib.parse import urljoin
>>> 
>>> base_dir_url = Path(os.path.realpath(os.getcwd())).as_uri() + '/'
>>> base_file_url = urljoin(base_dir_url, 'index.json')
>>> 
>>> json_str = """{"real": [1, 2, 3, 4], "ref": {"$ref": "test.json#/cat"}}"""
>>> data = jsonref.loads(json_str, base_uri=base_file_url)
>>> pprint(data) 
{'real': [1, 2, 3, 4], 'ref': 'woof'}
>>> 

I know this is even older now, but I finally added an example to the docs. ๐Ÿ˜„ It's on the beta docs right now https://jsonref.readthedocs.io/en/v1.0.0b1/#a-note-on-base-uri

Thank you @gazpachoking