需要了解json schema验证中contains和items关键字的区别
我正在使用Python的jsonschema验证库来进行模式验证,下面是我使用的代码片段、模式版本和示例json数据。我的问题是,当我使用模式版本一,其中使用了contains关键字时,从代码片段得到的错误响应非常笼统,它没有给出逐个元素的验证失败原因。但是当我使用稍微修改过的模式,改为使用items而不是contains时,同样的代码片段就能在元素级别提供详细的错误信息。
有人能告诉我,为什么会这样吗?是因为使用contains关键字时就只能这样,还是我在代码片段中漏掉了什么?
json模式版本一:
{
"$schema": "http://json-schema.org/draft/2019-09/schema#",
"type": "array",
"contains": {
"type": "number"
},
"minContains": 2,
"maxContains": 5
}
json模式版本二:
{
"$schema": "http://json-schema.org/draft/2019-09/schema#",
"type": "array",
"items": {
"type": "number"
},
"minContains": 2,
"maxContains": 5
}
json数据:
["", "1234"]
代码片段:
import json
import jsonschema
from jsonschema import Draft201909Validator
from jsonschema.exceptions import ValidationError
json_file = 'json_schema_validation/sample.json'
json_schema_file = 'json_schema_validation/sample_schemav2.json'
with open(json_file) as f:
rec = json.load(f)
with open(json_schema_file) as f:
schema = json.load(f)
v = Draft201909Validator(schema)
errors = sorted(v.iter_errors(rec), key=lambda e: e.path)
for error in errors:
print("---------------------------------------")
print("json_path list:", list(error.path))
print("error_message:", error.message)
使用模式版本二时的输出:
---------------------------------------
json_path list: [0]
error_message: '' is not of type 'number'
---------------------------------------
json_path list: [1]
error_message: '1234' is not of type 'number'
使用模式版本一时的输出:
---------------------------------------
json_path list: []
error_message: ['', '1234'] does not contain items matching the given schema
2 个回答
1
根据Json Schema的文档,
Contains的意思是数组中至少有一个元素是有效的。
Items的意思是数组中的所有元素都是有效的。
https://json-schema.org/understanding-json-schema/reference/array
所以,是否要检查至少一个元素有效还是所有元素都有效,取决于你的具体需求。
1
根据JSON Schema 的参考资料,关于数组的验证:
在数组中,
items
的规则必须适用于数组里的每一个元素,而contains
的规则只需要适用于数组中的一个或多个元素。
文档中有一些例子可以看到,items
的验证要求数组中的所有值都必须符合这个规则。但对于 contains
来说,只要有一个有效的值就足够了,这样就算符合要求。
这也解释了为什么在 items
的特定情况下,错误信息会比较详细。