如何在JSON Schema中用oneOf校验两个数组字段的互斥规则?
JSON Schema校验两个数组字段的解决方案
你的需求可以通过JSON Schema实现,核心是用oneOf覆盖三种合法场景:仅categories非空、仅positionedOffers非空、两个都为空。你当前的Schema缺少了“两个都为空”的场景,导致这种情况会校验失败,同时需要调整oneOf子Schema的结构确保约束生效。
修改后的Schema(适配draft-04)
var schema = { "id": "https://kitoutapi.lrsdedicated.com/v1/json_schemas/login-request#", "$schema": "http://json-schema.org/draft-04/schema#", "description": "Login request schema", "type": "object", "properties": { "categories": { "type": "array" }, "positionedOffers": { "type": "array" } }, "additionalProperties": false, "oneOf": [ // 场景1:仅positionedOffers非空,categories为空 { "properties": { "categories": { "maxItems": 0 }, "positionedOffers": { "minItems": 1 } } }, // 场景2:仅categories非空,positionedOffers为空 { "properties": { "categories": { "minItems": 1 }, "positionedOffers": { "maxItems": 0 } } }, // 场景3:两个数组都为空 { "properties": { "categories": { "maxItems": 0 }, "positionedOffers": { "maxItems": 0 } } } ] };
关键调整说明
- 补充“双空”场景:在
oneOf中新增第三个子Schema,约束两个数组的maxItems都为0,覆盖“两个字段均可为空”的需求。 - 规范子Schema结构:将每个场景的字段约束嵌套在
properties中,确保JSON Schema引擎正确识别对目标字段的校验规则(原Schema直接将字段约束写在子Schema根节点,部分引擎可能无法正确解析)。
测试验证
- 你的测试数据
data1会匹配oneOf的第一个场景,校验通过。 - 若传入
{"categories": ["foo"], "positionedOffers": []},会匹配第二个场景,校验通过。 - 若传入
{"categories": [], "positionedOffers": []},会匹配第三个场景,校验通过。 - 若传入
{"categories": ["foo"], "positionedOffers": ["bar"]},三个场景都不匹配,校验失败,符合“同一时间仅一个字段可包含值”的要求。
扩展:允许字段不存在的情况
如果你的需求中“为空”包括字段本身不存在(而非仅空数组),可以将每个字段的约束改为anyOf,例如:
"categories": { "anyOf": [ { "type": "array", "maxItems": 0 }, { "not": { "required": ["categories"] } } ] }
不过这会增加Schema复杂度,需根据实际业务需求选择。
内容的提问来源于stack exchange,提问作者Muhammad Huzaifa
相关产品推荐
相关产品推荐

