如何用JSON Schema定义含固定常量与对象的可选混合结构数组?
JSON Schema 验证复杂数组结构的可行方案
核心需求梳理
先明确要验证的规则:
- 数组元素只能是固定不变的字符串常量(比如
"StringConstant")和结构统一的对象 - 对象有两种合法存在形式:
- 单独作为数组元素
- 被
[常量, 对象, 常量, 常量]这样的四元组包裹
- 所有字符串常量必须完全一致,所有对象的键结构必须相同
实现思路
你提到的anyOf是核心方向,结合JSON Schema的prefixItems、const、$defs、allOf这些关键字,可以精准实现规则验证,同时避免冗余代码。
完整Schema示例
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", // 限定数组元素只能是指定常量或符合结构的对象 "items": { "anyOf": [ { "const": "StringConstant" }, { "$ref": "#/$defs/standardObject" } ] }, "$defs": { // 定义统一的对象结构,替换成你实际的键值规则 "standardObject": { "type": "object", "properties": { "someKey1": { "type": "string" }, "someKey2": { "type": "number" } }, "required": ["someKey1"] }, // 定义合法的「常量-对象-常量-常量」四元组 "validObjectGroup": { "type": "array", "prefixItems": [ { "const": "StringConstant" }, { "$ref": "#/$defs/standardObject" }, { "const": "StringConstant" }, { "const": "StringConstant" } ], "additionalItems": false } }, "allOf": [ // 验证数组要么是纯对象数组,要么是合法组+纯对象的混合 { "anyOf": [ // 情况1:数组全是符合结构的对象 { "items": { "$ref": "#/$defs/standardObject" } }, // 情况2:数组包含至少一个合法组,其余元素要么是合法组要么是纯对象 { "contains": { "$ref": "#/$defs/validObjectGroup" }, "additionalItems": { "anyOf": [ { "$ref": "#/$defs/standardObject" }, { "$ref": "#/$defs/validObjectGroup" } ] } } ] }, // 禁止出现孤立的常量(比如单独的一个StringConstant,不属于任何合法组) { "not": { "contains": { "const": "StringConstant", "not": { "oneOf": [ // 是合法组的第一个元素 { "prefixItems": [{}, { "const": "StringConstant" }, {}, {}] }, // 是合法组的第三个元素 { "prefixItems": [{}, {}, {}, { "const": "StringConstant" }] }, // 是合法组的第四个元素 { "prefixItems": [{}, {}, {}, {}, { "const": "StringConstant" }] } ] } } } } ] }
方案说明
- 复用定义:用
$defs把统一的对象结构和合法组抽离,减少重复代码,方便后续修改 - 元素范围限定:
items关键字确保数组里不会出现常量和标准对象之外的元素 - 分支验证:
anyOf区分纯对象数组和包含合法组的数组,覆盖你提到的所有4种情况 - 防非法常量:最后一个
not规则确保所有常量都属于合法组的一部分,不会出现孤立的常量字符串
这个Schema可以准确验证你列出的所有结构,同时满足常量统一、对象结构一致的要求。
内容的提问来源于stack exchange,提问作者KilledByCheese
相关产品推荐
相关产品推荐

