JSON Schema Draft 4条件必填校验中「非必填」规则失效问题
我帮你排查了这个JSON Schema的问题,核心是你误解了not和required组合的用法,导致非必填/禁止存在的规则不符合预期。下面是详细分析和修正方案:
问题根源
你用not: { required: ["field"] }来表达“字段不应存在”,这是完全错误的:
required: ["field"]的含义是该字段必须存在not: { required: ["field"] }的含义是该字段不是必须存在(也就是可以存在,也可以不存在),这和你想要的“字段禁止存在”完全不符。
另外,对于“非必填字段”,你不需要额外添加not规则——JSON Schema中,只要字段不在required数组里,默认就是非必填的(可以存在也可以不存在),额外的not规则反而会引入逻辑混乱。
修正后的JSON Schema
下面是符合你需求的Draft 4 Schema:
{ "type": "object", "properties": { "id": { "type": "integer" }, "url": { "type": "string" }, "profile": { "type": "string" }, "rate": { "type": "string" }, "trick": { "type": "boolean" }, "tag": { "type": "string" }, "type": { "type": "string" }, "name": { "type": "string" }, "code": { "type": "string" } }, "additionalProperties": false, "required": ["url", "profile"], "oneOf": [ { "properties": { "profile": { "enum": ["profile1"] }, "code": { "not": {} }, "name": { "not": {} }, "type": { "not": {} } }, "required": ["rate", "trick", "tag"] }, { "properties": { "profile": { "enum": ["profile2"] } }, "required": ["code"] }, { "properties": { "profile": { "enum": ["profile3"] } } } ] }
关键调整说明
Profile 1 分支
- 添加
required: ["rate", "trick", "tag"]确保这三个字段必须存在 - 将
code、name、type设置为{ "not": {} }:空Schema会匹配任何值,not之后就表示任何值都不合法,从而实现“这些字段禁止存在”的要求。
- 添加
Profile 2 分支
- 仅保留
required: ["code"]确保code必填 - 移除了多余的
not: { required: [...] }规则:rate、tag、trick默认是非必填的,无需额外限制。
- 仅保留
Profile 3 分支
- 仅指定profile值为profile3,无需其他规则:所有目标字段默认都是非必填的(可以存在也可以不存在),完全符合你的规则3。
关于你标记的“无效输入”
你提供的示例{"url": "url", "profile": "profile3", "code": ""},根据规则3(字段均为非必填),这个输入应该是有效的。如果你的实际需求是profile3时这些字段必须不存在,那需要把profile3分支修改成和profile1类似的结构:
{ "properties": { "profile": { "enum": ["profile3"] }, "rate": { "not": {} }, "trick": { "not": {} }, "tag": { "not": {} }, "code": { "not": {} }, "name": { "not": {} }, "type": { "not": {} } } }
内容的提问来源于stack exchange,提问作者Anbarasan




