【问题标题】:Using multiple anyOf inside oneOf在 oneOf 中使用多个 anyOf
【发布时间】:2019-03-23 04:58:36
【问题描述】:

我想创建一个模式,其中我将在“oneOf”中拥有多个对象,其中将有许多任意格式的对象,其中一些键可以是必需的类型(这部分有效) 我的架构:-

{
    "description": "schema v6",
    "type": "object",
    "oneOf": [
    {
    "properties": {
    "Speed": {
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/speed"
          },
          {
            "$ref": "#/definitions/SituationType"
          }
        ]
      },
      "required": [
        "speed"
      ]
    }
  },
  "additionalProperties": false
        }
      ],
      "definitions": {
        "speed": {
          "description": "Speed",
          "type": "integer"
        },
        "SituationType": {
          "type": "string",
          "description": "Situation Type",
          "enum": [
            "Advice",
            "Depend"
              ]
            }
          }
        }

但是当我尝试验证此架构时,我能够验证一些不正确的值,例如

    {
      "Speed": {
        "speed": "ABC",//required
        "SituationType1": "Advisory1" //optional but key needs to be correct
      }
    }

我期待的正确反应是

    {
      "Speed": {
        "speed": "1",
        "SituationType": "Advise" 
      }
    }

【问题讨论】:

  • 恐怕你落入了一个常见的陷阱。 additionalProperties 不能“看穿”anyOf 或任何 ...Of 关键字。我将在答案中进一步解释。
  • 实际上,您混淆了一些问题!不用担心,在这里为您提供帮助 =]

标签: json schema jsonschema


【解决方案1】:

首先,您需要正确设置架构类型,否则实施可能会假定您使用的是最新的 JSON 架构版本(当前为 Draft-7)。

因此,在您的架构根目录中,您需要以下内容:

"$schema": "http://json-schema.org/draft-06/schema#",

其次,items 仅适用于目标是数组的情况。 目前,您的架构仅检查以下内容:

如果根对象具有“速度”属性,则它的键必须为 “速度”。根对象不能有任何其他属性。

没有别的了。

您对definitions 的使用以及您引用它们的方式可能不是您想要的。

您似乎希望Speed 包含必须是整数的speed,以及可选的SituationType,它必须是字符串,受枚举限制,仅此而已。

这是我基于此的架构,它根据您给定的示例数据正确通过和失败:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "type": "object",
  "oneOf": [
    {
      "properties": {
        "Speed": {
          "properties":{
            "speed": {
              "$ref": "#/definitions/speed"
            },
            "SituationType": {
              "$ref": "#/definitions/SituationType"
            }
          },
          "required": [
            "speed"
          ],
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
  ],
  "definitions": {
    "speed": {
      "description": "Speed",
      "type": "integer"
    },
    "SituationType": {
      "type": "string",
      "description": "Situation Type",
      "enum": [
        "Advice",
        "Depend"
      ]
    }
  }
}

您需要为Speed 定义属性,否则您无法阻止其他属性,因为additionalProperties 仅受相邻properties 键的影响。我们希望在 draft-8 中创建一个新关键字来支持这种行为,但您的示例中似乎不需要它 (Huge Github issue in relation)。

现在将 additionalProperties false 添加到 Speed 架构中会阻止该对象中的其他键。

我怀疑给定您的问题标题,这里可能有更多的模式在起作用,并且您已经为这个问题简化了它。如果您有更详细的架构和更复杂的问题,我也很乐意提供帮助。

【讨论】:

猜你喜欢
  • 2020-02-03
  • 1970-01-01
  • 2022-01-14
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
相关资源
最近更新 更多