如何用JSON Schema验证下级结构中至少存在一个指定属性?
JSON Schema实现下级结构特定属性验证方案
针对你需要的三个验证要求:
- 单个子结构需匹配
has_C与C的对应关系(has_C: true必须含C,has_C: false不能含C) - 所有子结构中至少存在一个含
C的项
下面分两种常见的子结构组织方式给出具体实现:
情况1:子结构为对象的属性值(如item_1、item_2这类动态键名的对象)
完整Schema
{ "type": "object", // 定义每个子项的验证规则 "additionalProperties": { "type": "object", "properties": { "has_C": { "type": "boolean" }, "C": { "type": "string" } // 可根据实际需求调整C的类型 }, "required": ["has_C"], // has_C为true时必须包含C "if": { "properties": { "has_C": { "const": true } }, "required": ["has_C"] }, "then": { "required": ["C"] }, // has_C为false时必须不包含C "else": { "not": { "required": ["C"] } } }, // 确保至少有一个子项包含C属性 "not": { "additionalProperties": { "not": { "required": ["C"] } } } }
规则解释
- 子项基础规则:通过
additionalProperties约束所有动态键名的子项,必须包含has_C布尔属性,并通过if/then/else实现has_C与C的关联验证:- 当
has_C为true,强制要求存在C属性; - 当
has_C为false,强制要求不存在C属性。
- 当
- 全局存在性规则:通过
not嵌套规则反向验证——"并非所有子项都不含C",等价于"至少有一个子项含C"。
情况2:子结构为数组元素
如果你的子结构是数组形式(而非动态键名对象),可以直接用contains关键字实现全局存在性验证,更简洁:
完整Schema
{ "type": "array", // 定义每个数组元素的验证规则 "items": { "type": "object", "properties": { "has_C": { "type": "boolean" }, "C": { "type": "string" } // 可根据实际需求调整C的类型 }, "required": ["has_C"], "if": { "properties": { "has_C": { "const": true } }, "required": ["has_C"] }, "then": { "required": ["C"] }, "else": { "not": { "required": ["C"] } } }, // 确保数组中至少有一个元素包含C属性 "contains": { "required": ["C"] } }
规则解释
items部分的子项规则和对象型完全一致;contains是JSON Schema针对数组的原生关键字,直接指定"数组中至少有一个元素符合required: ["C"]的规则",完美匹配你需要的"至少存在一个C"的要求。
测试用例验证结果
item_1({"has_C": true, "C": "xxx"}):符合所有规则,验证通过;item_4({"has_C": true}):违反has_C: true需含C的规则,验证失败;item_3({"has_C": false, "C": "xxx"}):违反has_C: false不能含C的规则,验证失败;- 若所有子项都不含
C:违反全局存在性规则,验证失败。
内容的提问来源于stack exchange,提问作者BGaraiko
相关产品推荐
相关产品推荐

