如何通过JSON Schema的if/then实现顶层无pollInterval时子块必填该字段?
问题修复方案
你的核心问题出在if/then的作用域和条件判断逻辑上,下面是具体的修复步骤和说明:
错误原因拆解
- 作用域搞错了:你把if/then写在了
contents的Schema内部,导致条件判断的是contents子对象是否有pollInterval,而不是顶层对象是否缺失该属性。 - 条件写法错误:
"not": {"properties": {"pollInterval": {}}}是在描述Schema结构(表示当前Schema不含pollInterval属性),而不是校验实例数据是否缺失该属性。
修正后的完整Schema
{ "properties": { "p1": {}, "p2": {}, "pollInterval": {}, "contents": { "anyOf": [ { "properties": { "pollInterval": {}, // 保留你原来的其他属性定义 } }, { "properties": { "pollInterval": {}, // 保留你原来的其他属性定义 } } ] } }, // 判断顶层对象未提供pollInterval属性 "if": { "not": { "required": ["pollInterval"] } }, // 触发规则:强制contents的任意子Schema必须包含pollInterval "then": { "properties": { "contents": { "anyOf": [ { "required": ["pollInterval"] }, { "required": ["pollInterval"] } ] } } } }
更简洁的复用写法
如果不想重复编写anyOf结构,可以用$ref复用原有的contents Schema,再叠加必填约束:
{ "properties": { "p1": {}, "p2": {}, "pollInterval": {}, "contents": { "anyOf": [ { "properties": { "pollInterval": {}, // 保留原有属性 } }, { "properties": { "pollInterval": {}, // 保留原有属性 } } ] } }, "if": { // Draft 7+ 可用的更直接写法:判断顶层缺失pollInterval "missingProperty": "pollInterval" }, "then": { "properties": { "contents": { "allOf": [ // 复用原有的contents校验规则 { "$ref": "#/properties/contents" }, // 叠加必填约束 { "anyOf": [ { "required": ["pollInterval"] }, { "required": ["pollInterval"] } ] } ] } } } }
验证逻辑说明
- 当顶层存在
pollInterval时,if条件不触发,contents的子Schema保持原有非必填规则。 - 当顶层缺失
pollInterval时,then条件生效,强制contents必须匹配anyOf中的某一个子Schema,且该子Schema的pollInterval为必填项。
内容的提问来源于stack exchange,提问作者AC2199
相关产品推荐
相关产品推荐

