如何根据属性存在性切换JSON Schema?现有实现异常求助
问题诊断与修复方案
嘿,我一眼就看出问题所在了——你错误地用了patternProperties关键字,它的作用和你想的完全不一样!
为什么原来的逻辑会出错?
patternProperties是用来匹配对象的属性名的,比如你写的"^.+$"会匹配对象里每一个非空名称的属性,然后对每个属性值应用里面的if/then/else规则。但你的需求是判断整个对象有没有id属性,再切换对应的schema,把逻辑嵌套在patternProperties里完全是南辕北辙,这就导致验证器的逻辑混乱,出现了和预期相反的报错。
正确的实现方式
你需要把if/then/else直接放在根对象的schema层级,让它直接判断整个对象的结构:
final = { "type": "object", "if": { "required": ["id"] }, "then": existing_sample, "else": sample, "additionalProperties": False }
逻辑说明
- 根节点声明这是一个
object类型,符合你的数据结构需求。 if条件很简单:检查对象是否包含id这个必填属性——只要对象里有id字段,就会触发then分支的existing_sample规则。- 如果对象没有
id字段,就会自动走到else分支,用sample规则来验证,完全符合你最初的设计逻辑。 - 根节点的
additionalProperties: False可以保留,不过其实sample和existing_sample内部已经各自设置了这个规则,所以这里省略也不影响验证效果。
测试验证
- 当传入带
id的对象时,会严格遵循existing_sample:要求id必填,只能有id、protocols、measurements这几个属性,额外属性会直接报错。 - 当传入不带
id的对象时,会自动切换到sample规则:要求description和owner_id必填,不会再出现id必填的错误提示。
这样就能完美实现你想要的“根据id是否存在切换JSON Schema”的需求啦!
内容的提问来源于stack exchange,提问作者MaterialZ




