如何用JSON Schema校验数组中仅单个元素含指定属性?
数组属性唯一性校验方案
针对你要校验数组里filename和format各自只能在单个元素里出现,而且每个属性至少得出现一次的需求,用JSON Schema就能实现,之前加format后失效大概率是没正确组合多属性的校验规则,下面是具体解决办法:
核心思路
对每个要管控的属性(filename、format),分别做三个限制:
- 数组里必须有至少一个元素包含该属性
- 数组里最多只能有一个元素包含该属性
完整校验规则示例
{ "type": "array", "items": { "type": "object", "properties": { "filename": { "type": "string" }, "format": { "type": "string" }, // 这里可以加其他允许的属性 "extraProp": { "type": "string" } }, "additionalProperties": false // 要是允许未定义的属性,就改成true }, // 先管filename:恰好出现一次 "contains": { "required": ["filename"] }, "minContains": 1, "maxContains": 1, // 再用allOf把format的校验规则组合进去,避免覆盖前面的filename规则 "allOf": [ { "contains": { "required": ["format"] }, "minContains": 1, "maxContains": 1 } ] }
验证示例
符合规则的JSON
[ { "filename": "invoice.pdf" }, { "format": "A4" }, { "extraProp": "2024" } ]
或者单个元素同时包含两个属性的情况也合法:
[ { "filename": "avatar.png", "format": "PNG" }, { "extraProp": "user123" } ]
不符合规则的JSON
filename出现多次:
[ { "filename": "file1.txt" }, { "filename": "file2.txt" }, { "format": "TXT" } ]
format完全没出现:
[ { "filename": "data.csv" }, { "extraProp": "sales" } ]
format出现多次:
[ { "filename": "report.docx" }, { "format": "DOCX" }, { "format": "PDF" } ]
为什么加format后失效?排查这几点
- 没用到
allOf组合规则:如果直接在根节点重复写contains、minContains,后面的规则会覆盖前面的,必须用allOf把两个属性的校验逻辑包起来,确保同时生效。 - 错误设置了属性必填:要是在
items的properties里给filename或format加了required,会强制每个元素都得有这个属性,和需求冲突,赶紧删掉。 - Schema版本太旧:
minContains和maxContains是JSON Schema 2019-09及以后版本才支持的,要是用的Draft 7这类旧版本,得换用not来实现“最多出现一次”的限制,示例如下:
// Draft 7兼容写法:限制filename最多出现一次 "not": { "contains": { "required": ["filename"] }, "minContains": 2 }
内容的提问来源于stack exchange,提问作者Elephant
相关产品推荐
相关产品推荐

