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

基于引用对象值的JSON Schema条件验证与关联约束咨询

问题背景

给定如下JSON结构:

{
    "sources": [
        {
            "id": "foo",
            "type": "a"
        },
        {
            "id": "bar",
            "type": "b"
        }
    ],
    "data": [
        {
            "source-id": "foo",
            "a-attribute": 10
        },
        {
            "source-id": "bar",
            "b-attribute": 20
        }
    ]
}

要求data数组中每个对象的source-id必须匹配sources数组中某一对象的id值,同时需要解决以下技术问题:

  1. 如何在JSON Schema中表达这一关联关系?
  2. 如何基于引用的sources对象的type属性值,对data对象应用条件子模式验证?
    进一步需求:当引用的source的type为a时,必须指定a-attribute且不能指定b-attribute;当type为b时,必须指定b-attribute且不能指定a-attribute。该需求能否通过JSON Schema实现,还是需要自定义验证代码?

问题解答

1. 在JSON Schema中表达source-id与sources.id的关联关系

可以使用JSON Schema Draft 2019-09及后续版本支持的$data关键字(部分验证器需手动启用该扩展支持),结合动态引用实现关联校验:

针对data数组中的每个对象,其source-id字段的取值必须存在于sources数组所有对象的id集合中。示例Schema片段如下:

{
  "type": "object",
  "properties": {
    "sources": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "type": { "type": "string", "enum": ["a", "b"] }
        },
        "required": ["id", "type"]
      }
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "source-id": {
            "type": "string",
            "$data": "/sources/*/id"
          }
        },
        "required": ["source-id"]
      }
    }
  },
  "required": ["sources", "data"]
}

$data": "/sources/*/id"表示source-id的取值必须匹配sources数组中任意一个元素的id值,以此实现关联校验。

2. 基于source.type的条件子模式验证及进一步需求实现

该需求完全可以通过JSON Schema实现,无需编写自定义验证代码。核心思路是结合$data关键字动态获取对应source的type值,再使用if/then/else条件关键字进行分支校验:

完整Schema示例如下:

{
  "type": "object",
  "properties": {
    "sources": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "type": { "type": "string", "enum": ["a", "b"] }
        },
        "required": ["id", "type"],
        "additionalProperties": false
      },
      "uniqueItems": true,
      "items": { "properties": { "id": { "uniqueItems": true } } }
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "source-id": {
            "type": "string",
            "$data": "/sources/*/id"
          },
          "a-attribute": { "type": "integer" },
          "b-attribute": { "type": "integer" }
        },
        "required": ["source-id"],
        "additionalProperties": false,
        // 根据关联source的type执行条件校验
        "if": {
          "properties": {
            "source-id": {
              "$data": "/sources/[?(@.type == 'a')]/id"
            }
          }
        },
        "then": {
          "required": ["a-attribute"],
          "not": { "required": ["b-attribute"] }
        },
        "else": {
          "if": {
            "properties": {
              "source-id": {
                "$data": "/sources/[?(@.type == 'b')]/id"
              }
            }
          },
          "then": {
            "required": ["b-attribute"],
            "not": { "required": ["a-attribute"] }
          }
        }
      }
    }
  },
  "required": ["sources", "data"]
}

关键逻辑说明:

  • 使用$data": "/sources/[?(@.type == 'a')]/id"筛选出所有type为a的source的id,判断当前source-id是否属于该集合;
  • 若匹配,则进入then分支:要求必须包含a-attribute,同时禁止出现b-attribute;
  • 同理,对type为b的source执行反向校验;
  • 通过additionalProperties: false确保data对象不会出现其他未定义的属性。

注意:部分JSON Schema验证器对JSONPath的支持程度不同,需确认所使用的验证器支持$data关键字及[?()]这类筛选表达式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:05:34