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

关于JSON Schema属性合并扩展、数组项属性复用及$switch内部使用的咨询

JSON Schema 常见问题解答

我来逐个解答你的问题,都是JSON Schema里很常见的场景:

问题1:如何在JSON Schema中合并或扩展属性?

JSON Schema里最常用的方式是使用allOf关键字来合并多个schema的属性,实现扩展效果。你可以先定义一个基础schema,然后通过allOf引入它,再添加或覆盖额外的属性。

举个例子,先定义基础的用户schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "baseUser": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" }
      },
      "required": ["id", "name"]
    }
  }
}

如果要扩展出管理员用户,只需要用allOf包含基础schema,再添加专属属性:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    { "$ref": "#/definitions/baseUser" },
    {
      "type": "object",
      "properties": {
        "role": { "type": "string", "enum": ["admin", "superadmin"] }
      },
      "required": ["role"]
    }
  ]
}

如果需要覆盖基础schema里的属性(比如修改name的规则),直接在allOf的后续schema里重新定义该属性即可,后续的规则会覆盖前面的(具体优先级遵循JSON Schema的合并规则)。

问题2:数组项既有共同属性也有差异化属性,能否通过差异化属性扩展/修补共同属性?

完全可以!你可以先定义所有数组项的共同属性schema,然后针对不同类型的项,用allOf结合oneOf/anyOf来实现“基础属性+差异化属性”的结构。

举个例子,数组里的项都有id和type属性,但type为user时需要email,为admin时需要role:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "commonItem": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "type": { "type": "string", "enum": ["user", "admin"] }
      },
      "required": ["id", "type"]
    },
    "userItem": {
      "allOf": [
        { "$ref": "#/definitions/commonItem" },
        {
          "type": "object",
          "properties": {
            "email": { "type": "string", "format": "email" }
          },
          "required": ["email"]
        }
      ]
    },
    "adminItem": {
      "allOf": [
        { "$ref": "#/definitions/commonItem" },
        {
          "type": "object",
          "properties": {
            "role": { "type": "string", "enum": ["admin", "superadmin"] }
          },
          "required": ["role"]
        }
      ]
    }
  },
  "type": "array",
  "items": {
    "oneOf": [
      { "$ref": "#/definitions/userItem" },
      { "$ref": "#/definitions/adminItem" }
    ]
  }
}

这样数组里的每个项都会先满足共同属性的规则,再根据type匹配对应的差异化属性要求。

问题3:能否在对象属性内部使用$switch?

首先要明确:标准JSON Schema规范中并没有$switch这个关键字——你提到的根层级可用的$switch大概率是某个JSON Schema验证库的扩展(比如Ajv的自定义关键字)。

不过,标准JSON Schema提供了if/then/else关键字,可以在对象属性内部实现条件判断的逻辑,完全能替代$switch的大部分场景。

比如,我们可以在对象的属性定义里,根据其他属性的值来动态调整当前属性的规则:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "accountType": { "type": "string", "enum": ["personal", "business"] },
    "taxId": {
      "type": "string",
      "if": {
        "properties": { "accountType": { "const": "business" } }
      },
      "then": { "minLength": 9 },
      "else": { "not": {} } // 个人账号不需要taxId,这里用not{}表示不允许出现
    }
  }
}

如果你的验证库支持$switch扩展(比如Ajv),那通常也可以在属性内部使用它,写法类似根层级,但要注意不同库的具体语法要求。不过更推荐使用标准的if/then/else,因为它的兼容性更好,所有支持Draft 7及以上版本的验证库都能识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:13:37