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