JSON Schema数组中多if-then子句验证失效问题咨询(Draft 7)
问题描述
我研究这个问题许久,仍未找到解决方案。
待验证的JSON结构如下:
[ { "type": "label", "element": "text_lbl_1", "value": "Some text here" }, { "type": "label", "element": "text_lbl_2", "value": 3 }, { "type": "image", "element": "im_url_1", "value": "https://example.com/image/kartofen.png" } ]
这是一个对象数组,我需要验证type与value的类型匹配:
label类型对应的value必须是字符串image类型对应的value必须是URL格式的字符串
我编写的JSON Schema如下:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "required": [ "type", "element", "value" ], "allOf": [ { "if": { "properties": { "type": { "const": "label" } }, "required": [ "type" ], "then": { "properties": { "value": { "type": "string" } } } } }, { "if": { "properties": { "type": { "const": "image" } }, "required": [ "type" ], "then": { "properties": { "value": { "type": "string", "format": "uri" } } } } } ] } }
但上述JSON应该验证失败(第二个label的value为数字,不符合要求),实际却未检测出错误。我使用Python的jsonschema库,采用Draft 7版本进行验证,请问我哪里出错了?
错误分析与修正方案
核心错误
你的Schema存在两个关键问题:
then子句未强制约束value的规则:JSON Schema中,properties仅声明属性的规则,但不会主动验证属性是否符合该规则——即使value存在,只要没明确绑定约束,就不会触发类型检查。allOf逻辑不合适:每个对象的type只能是label或image中的一种,用allOf会要求同时匹配两个if/then条件,这显然不符合实际场景,应该用oneOf确保对象仅匹配其中一种类型的规则。
修正后的Schema(推荐oneOf写法)
这种写法逻辑更清晰,直接将type和对应value的约束绑定:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "required": ["type", "element", "value"], "oneOf": [ { "properties": { "type": { "const": "label" }, "value": { "type": "string" } }, "required": ["type", "value"] }, { "properties": { "type": { "const": "image" }, "value": { "type": "string", "format": "uri" } }, "required": ["type", "value"] } ] } }
若坚持使用if/then结构的修正版
需要在then子句中明确强制value符合约束,同时替换allOf为oneOf:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "required": ["type", "element", "value"], "oneOf": [ { "if": { "properties": { "type": { "const": "label" } }, "required": ["type"] }, "then": { "properties": { "value": { "type": "string" } }, "required": ["value"] } }, { "if": { "properties": { "type": { "const": "image" } }, "required": ["type"] }, "then": { "properties": { "value": { "type": "string", "format": "uri" } }, "required": ["value"] } } ] } }
Python验证注意事项
使用jsonschema库时,默认不会验证format规则(比如uri),需要手动启用格式检查器:
import jsonschema # 加载你的修正后的schema和待验证数据 schema = ... data = ... # 启用格式检查 validator = jsonschema.Draft7Validator(schema, format_checker=jsonschema.FormatChecker()) # 获取所有验证错误 errors = list(validator.iter_errors(data)) for error in errors: print(error.message)
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

