如何基于JSON Schema实现根据数组对象的tag字段值验证对应value字段
如何基于JSON Schema实现根据数组对象的tag字段值验证对应value字段
嘿,我懂你现在的困扰——想让JSON Schema根据数组里每个对象的tag值,来对应校验value字段的格式,之前用allOf加if/then的写法没达到预期,因为所有条件都被同时检查了,对吧?别慌,咱们调整一下Schema的结构就能搞定这个需求!
问题根源
你之前用allOf包裹多个if/then规则时,JSON Schema会同时评估所有的if条件——只要某个if为真,对应的then就必须满足。但我们需要的是互斥的分支逻辑:每个对象只符合其中一种tag对应的规则,这时候allOf就不适用了,得换成oneOf或者嵌套的if/then/else结构。
方案一:用oneOf实现互斥分支
这种方式把每种tag对应的规则拆成独立的分支,确保每个数组对象只会匹配其中一个分支,非常直观:
{ "type": "object", "properties": { "alias": { "type": "string" }, "attributes": { "type": "array", "items": { "type": "object", "required": ["tag", "value"], "properties": { "tag": { "type": "string" }, "value": { "type": "string" } }, "oneOf": [ { "if": { "properties": { "tag": { "const": "collection date" } } }, "then": { "properties": { "value": { "pattern": "^\\d{4}$" } } } }, { "if": { "properties": { "tag": { "const": "geographic location" } } }, "then": { "properties": { "value": { "enum": ["North America", "Europe", "Asia"] } } } }, { "else": true } ] } } }, "required": ["alias", "attributes"] }
代码解释:
- 顶层定义了JSON的基本结构:
alias是字符串,attributes是数组。 - 数组的每个
item必须包含tag和value两个字段,默认都是字符串类型。 oneOf确保每个对象只匹配一个分支:- 第一个分支:当
tag等于collection date时,value必须符合四位数字的正则(这里用年份作为示例,你可以换成自己需要的正则)。 - 第二个分支:当
tag等于geographic location时,value必须在指定的枚举列表里。 - 第三个分支:匹配所有其他
tag的情况,value可以是任意字符串(因为已经在properties里限定了是字符串类型)。
- 第一个分支:当
方案二:嵌套if/then/else实现流程化校验
如果你更喜欢线性的逻辑流程,可以用嵌套的if/then/else,模拟“如果-否则如果-否则”的判断:
{ "type": "object", "properties": { "alias": { "type": "string" }, "attributes": { "type": "array", "items": { "type": "object", "required": ["tag", "value"], "properties": { "tag": { "type": "string" }, "value": { "type": "string" } }, "if": { "properties": { "tag": { "const": "collection date" } } }, "then": { "properties": { "value": { "pattern": "^\\d{4}$" } } }, "else": { "if": { "properties": { "tag": { "const": "geographic location" } } }, "then": { "properties": { "value": { "enum": ["North America", "Europe", "Asia"] } } }, "else": true } } } }, "required": ["alias", "attributes"] }
代码解释:
- 先检查当前对象的
tag是否是collection date,如果是就校验value的格式。 - 如果不是,接着检查是否是
geographic location,对应校验value的枚举值。 - 剩下的所有情况直接通过校验,
value可以是任意字符串。
测试示例
正确的测试数据:
{ "alias": "lodBeiA", "attributes": [ { "tag": "collection date", "value": "2021" }, { "tag": "geographic location", "value": "Europe" }, { "tag": "sample type", "value": "blood" } ] }
这个数据会顺利通过校验,每个tag对应的value都符合规则。
错误的测试数据:
{ "alias": "lodBeiA", "attributes": [ { "tag": "collection date", "value": "21" } ] }
这个数据会校验失败,因为collection date对应的value不符合四位数字的正则要求。
备注:内容来源于stack exchange,提问作者Isuru
相关产品推荐
相关产品推荐

