如何编写JSON Schema验证列表至多含一个指定可选字符串元素
如何编写符合要求的JSON Schema?
需求规则
目标JSON需满足以下要求:
- 根对象仅包含必填的
mylist数组字段,无其他额外字段 mylist数组的元素只能是字符串,可选值为"a"、"b"、"c"、"d"、"w"、"x"、"y"、"z"- 数组中最多只能包含一个来自
["w", "x", "y", "z"]的元素(该元素可选,可放在数组任意位置) - 数组元素需唯一,且至少有1个元素
有效示例
{"mylist": ["a", "b", "c", "d", "x"]} {"mylist": ["b", "a", "y"]} {"mylist": ["z", "b", "a"]} {"mylist": ["c"]} {"mylist": ["y"]}
无效示例
{"mylist": ["a", "b", "c", "d", "x", "y"]} // 包含多个额外元素
当前尝试的Schema
{ "type": "object", "properties": { "mylist": { "type": "array", "items": { "type": "string", "enum": ["a", "b", "c", "d", "w", "x", "y", "z"] }, "minItems": 1, "uniqueItems": true } }, "required": ["mylist"], "additionalProperties": false }
该Schema的问题:未限制["w", "x", "y", "z"]元素的数量,无法阻止数组中出现多个这类元素。
正确的JSON Schema
方案1(兼容旧版本Schema)
通过not+重复contains实现限制,适用于不支持maxContains的版本:
{ "type": "object", "properties": { "mylist": { "type": "array", "items": { "type": "string", "enum": ["a", "b", "c", "d", "w", "x", "y", "z"] }, "minItems": 1, "uniqueItems": true, // 排除包含至少两个额外元素的情况 "not": { "contains": {"enum": ["w", "x", "y", "z"]}, "contains": {"enum": ["w", "x", "y", "z"]} } } }, "required": ["mylist"], "additionalProperties": false }
方案2(Schema 2019-09及以上版本推荐)
使用maxContains更清晰地实现限制:
{ "type": "object", "properties": { "mylist": { "type": "array", "items": { "type": "string", "enum": ["a", "b", "c", "d", "w", "x", "y", "z"] }, "minItems": 1, "uniqueItems": true, // 覆盖两种合法情况:无额外元素,或恰好一个额外元素 "anyOf": [ { "not": {"contains": {"enum": ["w", "x", "y", "z"]}} }, { "contains": {"enum": ["w", "x", "y", "z"]}, "maxContains": 1 } ] } }, "required": ["mylist"], "additionalProperties": false }
说明
- 方案1中,两次
contains意味着数组至少有两个匹配["w", "x", "y", "z"]的元素,not关键字直接排除这种非法情况 - 方案2中,
maxContains直接限制匹配元素的数量不超过1,anyOf分支同时允许"无额外元素"和"恰好一个额外元素"两种合法场景
内容的提问来源于stack exchange,提问作者Nitesh
相关产品推荐
相关产品推荐

