如何在python jsonschema文档中设置本地文件引用?
我有一套合规文件。某些文档包含对其他文档的引用(通过如何在python jsonschema文档中设置本地文件引用?,python,json,jsonschema,python-jsonschema,Python,Json,Jsonschema,Python Jsonschema,我有一套合规文件。某些文档包含对其他文档的引用(通过$ref属性)。我不希望托管这些文档,以便可以通过HTTP URI访问它们。因此,所有引用都是相对的。所有文档都位于本地文件夹结构中 如何理解如何正确使用本地文件系统加载引用的文档 例如,如果我有一个文件名为defs.json的文档,其中包含一些定义。我尝试加载引用它的不同文档,如: { "allOf": [ {"$ref":"defs.json#/definitions/basic_event"}, { "t
$ref
属性)。我不希望托管这些文档,以便可以通过HTTP URI访问它们。因此,所有引用都是相对的。所有文档都位于本地文件夹结构中
如何理解如何正确使用本地文件系统加载引用的文档
例如,如果我有一个文件名为
defs.json
的文档,其中包含一些定义。我尝试加载引用它的不同文档,如:
{
"allOf": [
{"$ref":"defs.json#/definitions/basic_event"},
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["page_load"]
}
},
"required": ["action"]
}
]
}
我收到一个错误refresolutionorr:
我使用linux设备可能很重要
(我写这篇文章是作为问答,因为我很难弄清楚这一点。)您必须为每个使用相对引用的模式构建一个自定义的
jsonschema.RefResolver
,并确保您的解析器知道给定模式在文件系统上的位置
比如
import os
import json
from jsonschema import Draft4Validator, RefResolver # We prefer Draft7, but jsonschema 3.0 is still in alpha as of this writing
abs_path_to_schema = '/path/to/schema-doc-foobar.json'
with open(abs_path_to_schema, 'r') as fp:
schema = json.load(fp)
resolver = RefResolver(
# The key part is here where we build a custom RefResolver
# and tell it where *this* schema lives in the filesystem
# Note that `file:` is for unix systems
schema_path='file:{}'.format(abs_path_to_schema),
schema=schema
)
Draft4Validator.check_schema(schema) # Unnecessary but a good idea
validator = Draft4Validator(schema, resolver=resolver, format_checker=None)
# Then you can...
data_to_validate = `{...}`
validator.validate(data_to_validate)
根据@chris-w提供的答案,我想用
jsonschema 3.2.0
做同样的事情,但他的答案没有完全涵盖这一点。我希望这个答案能帮助那些仍然在这个问题上寻求帮助但正在使用更新版本的软件包的人
要使用库扩展JSON模式,请执行以下操作:
RefResolver
和Validator
对象
这里是一个练习以上内容的剪报。尝试修改数据
字符串以删除所需属性之一:
import json
from jsonschema import RefResolver, Draft7Validator
base = """
{
"$id": "base.schema.json",
"type": "object",
"properties": {
"prop": {
"type": "string"
}
},
"required": ["prop"]
}
"""
extend = """
{
"allOf": [
{"$ref": "base.schema.json"},
{
"properties": {
"extra": {
"type": "boolean"
}
},
"required": ["extra"]
}
]
}
"""
data = """
{
"prop": "This is the property string",
"extra": true
}
"""
schema = json.loads(base)
extendedSchema = json.loads(extend)
resolver = RefResolver.from_schema(schema)
validator = Draft7Validator(extendedSchema, resolver=resolver)
jsonData = json.loads(data)
validator.validate(jsonData)
我最难弄清楚如何针对一组相互
$ref
的模式进行解析(我不熟悉JSON模式)。事实证明,关键是使用存储创建RefResolver
,这是一个从url映射到模式的dict
。
基于@devin-p的答案:
导入json
来自jsonschema导入引用器、Draft7Validator
base=“”
{
“$id”:“base.schema.json”,
“类型”:“对象”,
“财产”:{
“道具”:{
“类型”:“字符串”
}
},
“必需”:[“道具”]
}
"""
扩展“”
{
“$id”:“extend.schema.json”,
“allOf”:[
{“$ref”:“base.schema.json#”},
{
“财产”:{
“额外”:{
“类型”:“布尔”
}
},
“必需”:[“额外”]
}
]
}
"""
扩展_extend=“”
{
“$id”:“extend_extend.schema.json”,
“allOf”:[
{“$ref”:“extend.schema.json#”},
{
“财产”:{
“附加条款2”:{
“类型”:“布尔”
}
},
“必需”:[“额外2”]
}
]
}
"""
data=”“”
{
“prop”:“这是属性字符串”,
“额外”:正确,
“额外2”:错误
}
"""
schema=json.loads(基本)
extendedSchema=json.loads(extend)
extendedExtendSchema=json.load(extend\u extend)
架构存储={
架构['$id']:架构,
extendedSchema['$id']:extendedSchema,
extendedExtendSchema['$id']:extendedExtendSchema,
}
解析程序=从模式(模式,存储=模式存储)中引用解析程序
验证器=Draft7Validator(extendedExtendSchema,解析器=解析器)
jsonData=json.loads(数据)
validator.validate(jsonData)
上面是用jsonschema==3.2.0构建的
我的方法是将所有模式片段预加载到RefResolver缓存。我创建了一个要点来说明这一点:EDIT-1
修复了对base
架构的错误引用($ref
)。
更新示例以使用文档中的示例:
编辑-2
正如评论中所指出的,在以下内容中,我使用了以下导入:
from jsonschema import validate, RefResolver
from jsonschema.validators import validator_for
这只是@Daniel回答的另一个版本——对我来说是正确的。基本上,我决定在基本模式中定义$schema
。然后释放其他模式,并在实例化解析器时进行明确调用
- 事实上,
RefResolver.from_schema()
获取了(1)一些模式,以及(2)一个模式存储,我不太清楚这里的顺序和“某些”模式是否相关。下面就是你看到的结构
我有以下资料:
base.schema.json
:
{
“$schema”:”http://json-schema.org/draft-07/schema#"
}
definitions.schema.json
:
{
“类型”:“对象”,
“财产”:{
“街道地址”:{“类型”:“字符串”},
“城市”:{“类型”:“字符串”},
“状态”:{“类型”:“字符串”}
},
“必需”:[“街道地址”、“城市”、“州”]
}
address.schema.json
:
{
“类型”:“对象”,
“财产”:{
“账单地址”:{“$ref”:“definitions.schema.json”},
“shipping_address”:{“$ref”:“definitions.schema.json#”}
}
}
我喜欢这种设置有两个原因:
是对RefResolver.from_schema()
的更干净的调用:
base=json.load(打开('base.schema.json').read())
definitions=json.load(打开('definitions.schema.json').read())
schema=json.load(打开('address.schema.json').read())
架构存储={
base.get('$id','base.schema.json'):base,
definitions.get('$id','definitions.schema.json'):定义,
schema.get('$id','address.schema.json'):schema,
}
解析程序=从模式(基,存储=模式\u存储)中引用解析程序
然后,我从库提供的便捷工具中获益,它为您的模式提供了最佳的验证工具(根据您的$schema
键):
Valida
data.json
{
"prop": "This is the property",
"extra": true
}
#Set up schema, resolver, and validator on the base schema
baseSchema = json.loads(baseSchemaJSON) # Create a schema dictionary from the base JSON file
relativeSchema = json.loads(relativeJSON) # Create a schema dictionary from the relative JSON file
resolver = RefResolver.from_schema(baseSchema) # Creates your resolver, uses the "$id" element
validator = Draft7Validator(relativeSchema, resolver=resolver) # Create a validator against the extended schema (but resolving to the base schema!)
# Check validation!
data = json.loads(dataJSON) # Create a dictionary from the data JSON file
validator.validate(data)
import json
from jsonschema import RefResolver, Draft7Validator
base = """
{
"$id": "base.schema.json",
"type": "object",
"properties": {
"prop": {
"type": "string"
}
},
"required": ["prop"]
}
"""
extend = """
{
"allOf": [
{"$ref": "base.schema.json"},
{
"properties": {
"extra": {
"type": "boolean"
}
},
"required": ["extra"]
}
]
}
"""
data = """
{
"prop": "This is the property string",
"extra": true
}
"""
schema = json.loads(base)
extendedSchema = json.loads(extend)
resolver = RefResolver.from_schema(schema)
validator = Draft7Validator(extendedSchema, resolver=resolver)
jsonData = json.loads(data)
validator.validate(jsonData)
from jsonschema import validate, RefResolver
from jsonschema.validators import validator_for