【问题标题】:JSON schema validation Draft 7 two type of data for one fieldJSON schema 验证 Draft 7 一个字段的两种数据
【发布时间】:2026-02-01 09:45:01
【问题描述】:

我需要帮助为可能是对象或对象数组的值创建 JSON 架构。

  • lib: jsonschema==3.2.0
  • py: 3.8

我有 2 个来自服务器的响应:

第一:

{
"result": [
    {
        "brand": "Test"
    }
]}

秒:

{
"result": 
    {
        "brand": "Test"
    }
}

正如你所看到的,在第一种情况下,它是一个 obj 数组,第二个只是对象。

我的架构:

{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"required": [
    "result"
],
"properties": {
    "result": {
        "$id": "#/properties/result",
        "type": ["array", "object"],
        "additionalItems": true,
        "items": {
            "$id": "#/properties/result/items",
            "anyOf": [
                {
                    "$id": "#/properties/result/items/anyOf/0",
                    "type": "object",
                    "required": [
                        "brand"
                    ],
                    "properties": {
                        "brand": {
                            "$id": "#/properties/result/items/anyOf/0/properties/brand",
                            "type": "string"
                        }
                    },
                    "additionalProperties": true
                }
            ]
        }
    }
},
"additionalProperties": true}

第一种情况是返回数组,第二种情况是返回对象时检查“品牌”类型,否。

如何为一个字段“结果”设置两种类型以检查品牌类型?

【问题讨论】:

    标签: python-3.x jsonschema


    【解决方案1】:

    您的架构可以固定如下:

    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "$id": "http://example.com/example.json",
      "type": "object",
      "required": [
        "result"
      ],
      "properties": {
        "result": {
          "$id": "#/properties/result",
          "anyOf": [
            {
              "$id": "#/properties/result/items/brand",
              "type": "object",
              "properties": {
                "brand": {
                  "$id": "#/properties/result/items/anyOf/0/properties/brand",
                  "type": "string"
                }
              },
              "required": [
                "brand"
              ],
              "additionalProperties": true
            },
            {
              "$id": "#/properties/result/items/array",
              "type": "array",
              "items": {
                "$ref": "#/properties/result/items/brand"
              }
            }
          ]
        }
      },
      "additionalProperties": true
    }
    

    演示hereherehere

    但是,习惯上将架构的可重用部分提取到单独的 "definitions" 部分中,如下所示:

    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "$id": "http://example.com/example.json",
      "definitions": {
        "brand": {
          "type": "object",
          "properties": {
            "brand": {
              "$id": "#/properties/result/items/anyOf/0/properties/brand",
              "type": "string"
            }
          },
          "required": [
            "brand"
          ],
          "additionalProperties": true
        }
      },
      "type": "object",
      "required": [
        "result"
      ],
      "properties": {
        "result": {
          "$id": "#/properties/result",
          "anyOf": [
            {
              "$ref": "#/definitions/brand"
            },
            {
              "$id": "#/properties/result/items/array",
              "type": "array",
              "items": {
                "$ref": "#/definitions/brand"
              }
            }
          ]
        }
      },
      "additionalProperties": true
    }
    

    演示hereherehere

    注意事项:

    1. 要表示属性"result" 可能是两种不同的类型,请使用"anyof" 关键字作为属性架构。 "anyOf" 的值应该是一个数组,其中每个可能的类型(这里是 "brand" 对象或 "brand" 对象的数组)的架构作为数组项。

      请参阅:Multiple Types

    2. 为避免重复"brand" 对象的定义,您可以在为数组项定义架构时使用"$ref" 来引用先前给定的"brand" 架构。如上所述,习惯上将重用的子模式放入"definitions" 部分,但这不是必需的,"$ref" 可以通过JSON Pointer 语法引用任何模式项。

      请参阅:Reuse

    3. 当列表的项目只有一个模式时,不应使用"additionalItems"

      请参阅:List validation

    【讨论】: