You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按指定条件生成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"]
}

关键说明

  1. 可选字段处理:possibleValues 和 reference 未被加入required数组,默认即为可选字段,符合需求。
  2. 条件逻辑实现:
    • if 块匹配type等于float的情况
    • then 块要求此时必须存在numberDecimals字段
    • else 块定义非float类型时numberDecimals为可选的整数类型
  3. 为什么anyOf可能失效:如果之前的anyOf写法没有明确区分不同type的分支,或者分支间的约束有重叠,就会导致验证逻辑不严谨。if/then/else是JSON Schema中专门用于条件判断的关键字,逻辑更清晰,验证结果更可靠。

内容的提问来源于stack exchange,提问作者carboncheg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:23:13