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

如何使用JSON Schema拆分重构属性,实现多文件$ref引用?

首先你给出的示例中book.json和pencil.json的字段对应关系和原逻辑相反,原逻辑中Book类型关联domain/img_url/url字段、禁止content,Pencil类型关联content、禁止另外三个字段,以下方案会按原逻辑修正。

核心问题说明

  1. 同一对象下声明多个$ref会相互覆盖,JSON Schema规定$ref所在对象的其余属性会被忽略,你原来写的在properties下直接放两个$ref的写法是无效的。
  2. Draft-07及更早版本的additionalProperties: false只能识别当前同级properties内声明的字段,无法识别跨$ref引入的属性,要保证额外属性校验生效有两种方案可选。

方案1:兼容Draft-07版本,无需升级规范

1. 公共字段文件 common.json 维护通用属性

{
  "type": "object",
  "properties": {
    "id": { "type": "string" },
    "type": { "type": "string", "enum": ["Pencil", "Book"] },
    "title": { "type": "string" }
  },
  "required": ["id", "type", "title"]
}

2. Book类型专属文件 book.json 维护自身规则

{
  "type": "object",
  "properties": {
    "domain": { "type": "string" },
    "img_url": { "type": "string" },
    "url": { "type": "string" }
  },
  "if": {
    "properties": { "type": { "const": "Book" } }
  },
  "then": {
    "required": ["domain", "img_url", "url"],
    "not": { "required": ["content"] }
  }
}

3. Pencil类型专属文件 pencil.json 维护自身规则

{
  "type": "object",
  "properties": {
    "content": { "type": "string" }
  },
  "if": {
    "properties": { "type": { "const": "Pencil" } }
  },
  "then": {
    "required": ["content"],
    "not": {
      "anyOf": [
        { "required": ["domain"] },
        { "required": ["img_url"] },
        { "required": ["url"] }
      ]
    }
  }
}

4. 主入口文件 main.json 整合所有规则

需要把所有允许的字段都在主文件的properties中声明,保证additionalProperties: false生效:

{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "id": { "type": "string" },
    "type": { "type": "string", "enum": ["Pencil", "Book"] },
    "title": { "type": "string" },
    "content": { "type": "string" },
    "domain": { "type": "string" },
    "img_url": { "type": "string" },
    "url": { "type": "string" }
  },
  "allOf": [
    { "$ref": "./common.json" },
    { "$ref": "./book.json" },
    { "$ref": "./pencil.json" }
  ]
}

方案2:使用2019-09及以上版本规范,简化结构

如果可以升级JSON Schema版本,用unevaluatedProperties: false替代additionalProperties: false,它可以识别所有跨$ref引入的属性,不需要在主文件重复声明所有字段:

主入口文件简化为:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "type": "object",
  "unevaluatedProperties": false,
  "allOf": [
    { "$ref": "./common.json" },
    { "$ref": "./book.json" },
    { "$ref": "./pencil.json" }
  ]
}

后续修改子类型属性只需要改对应子文件即可,不需要调整主文件配置。

内容的提问来源于stack exchange,提问作者Samuel Da Costa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:30:06