基于枚举值的JSON Schema属性必填性校验问题求助
JSON Schema 条件校验问题解决
现有如下JSON Schema:
{ "type": "object", "properties": { "FileType": { "type": "string" }, "Version": { "type": "string" }, "Expt": { "type": "object", "properties": { "design": { "type": "string","enum": ["TS", "DR", "BC", "DP"] } }, "required": ["design"], "additionalProperties": false }, "Rout": { "type": "object", "properties": { "timeUnits": {"type": "string", "enum": ["sec", "min", "hr"] }, "setTime": { "type": "number", "minimum": 0.0, "maximum": 50 } }, "required": ["timeUnits"], "additionalProperties": false } } }
需要实现以下校验规则:
- 当
design为DR或BC时,Rout下的setTime必须存在; - 当
design为TS或DP时,setTime不得存在。
尝试过if-then-else、oneOf、allOf等组合,都无法正确校验——特别是design为TS或DP时,无法对setTime的出现抛出错误。
无效实例
setTime不允许存在的情况
{ "Expt": { "design": "TS" }, "Rout": { "timeUnits": "sec", "setTime":12 } }
setTime必填的情况
{ "Expt": { "design": "BC"}, "Rout": { "timeUnits": "sec" } }
有效实例
{ "Expt": { "design": "TS" }, "Rout": { "timeUnits": "sec" } }
{ "Expt": { "design": "BC" }, "Rout": { "timeUnits": "sec", "setTime":12 } }
解决方案
通过if-then-else结合required和not关键字可实现精准校验,核心是在else分支明确禁止setTime字段:
{ "type": "object", "properties": { "FileType": { "type": "string" }, "Version": { "type": "string" }, "Expt": { "type": "object", "properties": { "design": { "type": "string", "enum": ["TS", "DR", "BC", "DP"] } }, "required": ["design"], "additionalProperties": false }, "Rout": { "type": "object", "properties": { "timeUnits": { "type": "string", "enum": ["sec", "min", "hr"] }, "setTime": { "type": "number", "minimum": 0.0, "maximum": 50 } }, "required": ["timeUnits"], "additionalProperties": false } }, // 条件校验逻辑 "if": { "properties": { "Expt": { "properties": { "design": { "enum": ["DR", "BC"] } } } } }, "then": { "required": ["Rout"], "properties": { "Rout": { "required": ["setTime"] } } }, "else": { "properties": { "Rout": { // 明确禁止setTime字段存在 "not": { "required": ["setTime"] } } } } }
校验逻辑说明
if分支:判断Expt.design是否为DR或BC;then分支:要求Rout必须存在,且Rout.setTime为必填字段;else分支:针对design为TS或DP的情况,通过not: { required: ["setTime"] }明确禁止setTime出现在Rout中,只要该字段存在就会触发校验错误。
此方案可同时满足两种条件的严格校验,解决之前无法拦截非法setTime的问题。
内容的提问来源于stack exchange,提问作者Rani
相关产品推荐
相关产品推荐

