如何按指定条件生成JSON Schema并解决anyOf验证失效问题?
符合特定条件的JSON Schema实现方案
问题背景
给定如下JSON数据:
{ "headerInfo": { "id": 50 }, "characteristics": [ { "id": "123456789", "type": "float", "multiValued": false, "numberDecimals": 6, "length": 10, "caseSensitive": false, "entryFieldMask": "_,___.______", "unitOfMeasure": "P1", "additionalValues": true }, { "id": "15151511", "type": "float", "multiValued": false, "numberDecimals": 0, "possibleValues": [ { "valueLow": "60", "intervalType": "1" }, { "valueLow": "80", "intervalType": "1" } ], "length": 3, "caseSensitive": false, "entryFieldMask": "___", "unitOfMeasure": "P1", "additionalValues": false }, { "id": "489481561", "type": "string", "multiValued": false, "possibleValues": [ { "id": "A" }, { "id": "§" } ], "length": 1, "caseSensitive": true, "entryFieldMask": "", "additionalValues": false, "reference": { "name": "ghnfgjghjghk", "writable": false } }, { "id": "4616616161", "type": "date", "multiValued": false, "length": 10, "caseSensitive": false, "entryFieldMask": "DD.MM.YYYY", "additionalValues": true, "reference": { "name": "bfhwbvbjewbv", "writable": false } } ] }
需要生成满足以下规则的JSON Schema:
reference和possibleValues属性为可选字段- 当
type属性值为float时,numberDecimals属性为必填;否则该属性非必填
此前尝试用 anyOf 实现逻辑,但内部验证未生效,虽Postman显示验证成功,仍需正确实现方案。
正确实现方案
使用JSON Schema的if/then/else关键字可以精准实现这个条件逻辑,比anyOf更直观且不易出错。以下是完整的Schema:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "headerInfo": { "type": "object", "properties": { "id": { "type": "integer" } }, "required": ["id"] }, "characteristics": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "type": { "type": "string", "enum": ["float", "string", "date"] }, "multiValued": { "type": "boolean" }, "numberDecimals": { "type": "integer" }, "length": { "type": "integer" }, "caseSensitive": { "type": "boolean" }, "entryFieldMask": { "type": "string" }, "unitOfMeasure": { "type": "string" }, "additionalValues": { "type": "boolean" }, "possibleValues": { "type": "array", "items": { "type": "object", "oneOf": [ { "properties": { "valueLow": { "type": "string" }, "intervalType": { "type": "string" } }, "required": ["valueLow", "intervalType"] }, { "properties": { "id": { "type": "string" } }, "required": ["id"] } ] } }, "reference": { "type": "object", "properties": { "name": { "type": "string" }, "writable": { "type": "boolean" } }, "required": ["name", "writable"] } }, "required": ["id", "type", "multiValued", "length", "caseSensitive", "entryFieldMask", "additionalValues"], // 核心条件逻辑:type为float时必填numberDecimals "if": { "properties": { "type": { "const": "float" } } }, "then": { "required": ["numberDecimals"] }, // 非float类型时,numberDecimals可选 "else": { "properties": { "numberDecimals": { "type": "integer" } } } } } }, "required": ["headerInfo", "characteristics"] }
关键说明
- 可选字段处理:
possibleValues和reference未被加入required数组,默认即为可选字段,符合需求。 - 条件逻辑实现:
if块匹配type等于float的情况then块要求此时必须存在numberDecimals字段else块定义非float类型时numberDecimals为可选的整数类型
- 为什么anyOf可能失效:如果之前的
anyOf写法没有明确区分不同type的分支,或者分支间的约束有重叠,就会导致验证逻辑不严谨。if/then/else是JSON Schema中专门用于条件判断的关键字,逻辑更清晰,验证结果更可靠。
内容的提问来源于stack exchange,提问作者carboncheg
相关产品推荐
相关产品推荐

