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

如何在自引用JSON Schema中排除指定属性与关键字?

问题描述

原始JSON Schema如下:

{"$id": "http://example.com/names.json","type": "object","required": ["id", "name"],"additionalProperties": false,"properties": {"name": {"type": "string"},"id": {"type": "string"},"subscriptions": {"type": "object"}}}

需求是新增draftVersion属性用于存储草稿,要求:

  • 草稿可包含主对象的所有核心属性(name、id、subscriptions)
  • 草稿不能包含draftVersion属性,避免深层递归嵌套
  • 草稿无需遵循主对象的required约束(即草稿可以缺少id或name)
  • 草稿无需遵循主对象的additionalProperties: false约束(即草稿可以有额外属性)

之前尝试直接引用主Schema并添加not关键字的写法无效:

"draftVersion": {"$ref": "#","not": {"anyOf": [{"required": ["draftVersion"]}]}}

这种写法会将主Schema的required和additionalProperties: false规则带入草稿,导致草稿必须包含id和name、无法添加额外属性,同时递归引用仍允许草稿嵌套draftVersion。

解决方案

正确的做法是避免直接递归引用整个主Schema,而是单独定义草稿的规则,确保其与主对象的约束解耦。以下是符合需求的Schema:

{
  "$id": "http://example.com/names.json",
  "type": "object",
  "required": ["id", "name"],
  "additionalProperties": false,
  "properties": {
    "name": {"type": "string"},
    "id": {"type": "string"},
    "subscriptions": {"type": "object"},
    "draftVersion": {
      "type": "object",
      "properties": {
        "name": {"type": "string"},
        "id": {"type": "string"},
        "subscriptions": {"type": "object"}
      },
      "additionalProperties": true,
      "not": {"required": ["draftVersion"]}
    }
  }
}

规则说明

  1. 主对象规则:保留原有的required: ["id", "name"]和additionalProperties: false,确保主对象的合法性。
  2. 草稿规则:
    • 仅定义主对象的核心属性,未包含draftVersion,结合not: {"required": ["draftVersion"]}直接禁止草稿中出现draftVersion属性,从根源避免递归嵌套。
    • 未设置required约束,草稿可按需包含核心属性的任意组合(比如仅包含subscriptions)。
    • 设置additionalProperties: true,允许草稿包含核心属性之外的其他属性。

如果使用JSON Schema 2020-12及以上版本,还可以用$defs抽离核心属性提升复用性:

{
  "$id": "http://example.com/names.json",
  "$defs": {
    "coreProperties": {
      "properties": {
        "name": {"type": "string"},
        "id": {"type": "string"},
        "subscriptions": {"type": "object"}
      }
    }
  },
  "type": "object",
  "required": ["id", "name"],
  "additionalProperties": false,
  "properties": {
    "name": {"$ref": "#/$defs/coreProperties/properties/name"},
    "id": {"$ref": "#/$defs/coreProperties/properties/id"},
    "subscriptions": {"$ref": "#/$defs/coreProperties/properties/subscriptions"},
    "draftVersion": {
      "type": "object",
      "$ref": "#/$defs/coreProperties",
      "additionalProperties": true,
      "not": {"required": ["draftVersion"]}
    }
  }
}

修改后,你提供的合法示例:

{"name": "abc","id": "123","draftVersion": {"subscriptions": {"id": 123}}}

会被Schema验证通过,而包含嵌套draftVersion的对象则会被拒绝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 21:34:54