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

为何JSON Schema多元素条件验证仅单元素场景生效?

问题描述

我有如下JSON数据:

{
  "inputs": [
    {
      "term": {
        "units": "liters",
        "termType": "material"
      }
    },
    {
      "term": {
        "units": "kilogram",
        "termType": "crop"
      }
    }
  ]
}

需要验证的规则是:若inputs数组中任意元素的termType为material,则该元素的units必须为kilogram。

我编写了如下验证Schema:

{
  "allOf": [
    {
      "if": {
        "required": [
          "inputs"
        ],
        "properties": {
          "inputs": {
            "items": {
              "properties": {
                "term": {
                  "properties": {
                    "termType": {
                      "const": "material"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "inputs": {
            "items": {
              "properties": {
                "term": {
                  "properties": {
                    "units": {
                      "const": "kilogram"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  ]
}

使用ajv 6版本(启用draft 07)验证时,发现该规则仅在inputs数组仅包含单个material类型元素(如下所示)时会报错:

{
  "inputs": [
    {
      "term": {
        "units": "liters",
        "termType": "material"
      }
    }
  ]
}

但在包含两个元素的初始示例中不会报错,请问这是为什么?

问题原因

你的Schema逻辑错误在于if条件的判断逻辑不符合预期:

  • JSON Schema中,items关键字默认要求数组的所有元素都匹配指定的schema。所以你的if条件实际表达的是:“当inputs数组的每一个元素的term.termType都是material时”,才会触发then的验证。
  • 当inputs数组同时包含material和crop类型的元素时,if条件不满足(因为不是所有元素都是material),所以then分支不会执行,自然不会对units进行校验,也就不会报错。
  • 只有当数组里全是material类型元素时,if条件才会触发,此时then要求所有元素的units都是kilogram,所以单个错误元素会触发报错。
正确的验证Schema

要实现“任意material类型的元素必须满足units为kilogram”的规则,应该直接对数组的每个元素使用if/then逻辑,而不是对整个数组做判断:

{
  "properties": {
    "inputs": {
      "items": {
        "if": {
          "properties": {
            "term": {
              "properties": {
                "termType": {
                  "const": "material"
                }
              },
              "required": ["termType"]
            }
          },
          "required": ["term"]
        },
        "then": {
          "properties": {
            "term": {
              "properties": {
                "units": {
                  "const": "kilogram"
                }
              },
              "required": ["units"]
            }
          }
        }
      }
    }
  }
}

这个Schema的逻辑是:对inputs数组中的每一个元素单独校验——如果该元素的term.termType是material,那么它的term.units必须是kilogram。不管数组里有没有其他类型的元素,只要有material类型元素不符合units要求,就会触发报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:04:58