使用Python在json模式中完全展开$ref引用

2ul0zpep  于 2023-08-08  发布在  Python
关注(0)|答案(3)|浏览(149)

我们有一个相当大且复杂的JSON模式,其中包含许多通过$ref引用的包含。理想情况下使用Python和jsonschema,我希望采用这些模式并完全扩展引用(递归地)以获得完整的模式。
以dict的形式输出就很好了(jsonschema用来表示模式的标准数据结构)。

gc0ot86w

gc0ot86w1#

如果你查看JSON文档。
你会发现循环$ref不被推荐,但也不被禁止。因此,在这种情况下,不可能 * 完全展开 * 所有$ref
但是如果你确定你的$ref中没有循环,我建议你使用this repo,它在这种情况下帮助了我。代码非常简单,所以你可以自己修改它。

eivnm1vs

eivnm1vs2#

我已经测试过了,也可以推荐以下模块:
https://github.com/gazpachoking/jsonref
在PyPI上。documentation很好,最近才得到维护(2018年10月),语法是这样的,它是标准json模块的直接替代品:
从主页:

>>> from pprint import pprint
>>> import jsonref

>>> # An example json document
>>> json_str = """{"real": [1, 2, 3, 4], "ref": {"$ref": "#/real"}}"""
>>> data = jsonref.loads(json_str)
>>> pprint(data)  # Reference is not evaluated until here
{'real': [1, 2, 3, 4], 'ref': [1, 2, 3, 4]}

字符串

fiei3ece

fiei3ece3#

这里有一个解决方案,它能够扩展当前文档中的引用,即使是对外部JSON模式文件的引用,这些文件本身也可能引用其他JSON模式文件。
使用json.dumps()而不是print可以使JsonRef对象在输出时完全展开。

"""
Usage:
  json-schema-expand-refs.py <jsonfile>

Arguments:
  jsonfile   JSON schema file to have refs expanded

Options:
  -h --help     Show this screen.
  --version     Show version.
"""

from docopt import docopt
from jsonref import replace_refs
from pathlib import Path
import json

def load_json(file):
    with open(file, "r") as f:
        data = json.load(f)
    return data

if __name__ == "__main__":
    args = docopt(__doc__, version="0.1.0")
    jsonfile = args["<jsonfile>"]

    # replace_refs returns a copy of the document with refs replaced by JsonRef
    # objects.  It will resolve refences to other JSON schema files
    doc = replace_refs(
        load_json(jsonfile),
        merge_props=True,
        base_uri=Path(jsonfile).absolute().as_uri(),
    )
    print(json.dumps(doc, indent=2))

字符串

相关问题