如何使用JSON Schema约束数组最后一项结构及前置元素类型
实现方案
你可以通过JSON Schema的组合断言能力实现该约束,无需依赖暂未支持的reversePrefixItems类关键字,兼容JSON Schema 2019-09及以上版本的校验器。
核心实现逻辑如下:
- 约束数组至少包含1项,避免空数组不符合预期
- 约束除最后一项外的所有前置项只能为字符串类型
- 约束数组有且仅有1个符合结构要求的对象
- 约束该对象只能出现在数组最后一位,不允许后面出现其他元素
对应的Schema示例如下:
{ "type": "array", "minItems": 1, "items": { "anyOf": [ // 前置项的类型约束:字符串 { "type": "string" }, // 最后一项的结构约束 { "type": "object", "properties": { "object": { "const": "as" }, "last": { "const": "item" } }, "required": ["object", "last"], "additionalProperties": false } ] }, // 确保数组中存在且仅存在1个目标对象 "contains": { "type": "object", "properties": { "object": { "const": "as" }, "last": { "const": "item" } }, "required": ["object", "last"] }, "minContains": 1, "maxContains": 1, // 禁止目标对象之后出现任何元素 "allOf": [ { "not": { "items": { "contains": { "type": "object", "properties": { "object": { "const": "as" }, "last": { "const": "item" } }, "required": ["object", "last"] }, "items": true } } } ] }
验证效果
- 符合要求的数组示例:
["a", "b", {"object":"as", "last":"item"}]、[{"object":"as", "last":"item"}]均可正常通过校验 - 不符合要求的数组示例:
["a", {"object":"as", "last":"item"}, "b"](目标对象不在最后一位)、["a", "b"](缺少目标对象)、["a", {"object":"as", "last":"item"}, {"object":"as", "last":"item"}](存在多个目标对象)都会被校验器拦截。
如果你的校验器支持$data可选特性(部分主流校验器已实现),还可以用更简洁的写法直接校验数组最后一位:
{ "type": "array", "minItems": 1, "items": { "type": "string" }, "unevaluatedItems": { "type": "object", "properties": { "object": { "const": "as" }, "last": { "const": "item" } }, "required": ["object", "last"] } }
内容的提问来源于stack exchange,提问作者thybzi
相关产品推荐
相关产品推荐

