【问题标题】:JSON Schema Draft 7 issue in validating required property in array objectJSON Schema Draft 7 验证数组对象中所需属性的问题
【发布时间】:2020-05-12 13:24:48
【问题描述】:

我有这个 JSON Schema 文件(缩小到不显示与问题无关的内容):

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "urn:jsonschema:testing:frmwk",
  "type": "object",
  "title": "The root schema",
  "default": {},
  "required": [
    "processOrder"
  ],
  "additionalProperties": true,
  "properties": {
    "processOrder": {
      "$id": "#processOrder",
      "type": "array",
      "title": "The processOrder schema",
      "default": [],
      "additionalItems": true,
      "items": {
        "anyOf": [
          {
            "$id": "#0",
            "type": "object",
            "title": "The first anyOf schema",
            "default": {},
            "additionalProperties": true,
            "properties": {
              "cleanHistory": {
                "$id": "#cleanHistory",
                "type": "object",
                "title": "The cleanHistory schema",
                "default": {},
                "additionalProperties": true,
                "properties": {}
              }
            }
          },
          {
            "$id": "#3",
            "type": "object",
            "title": "The fourth anyOf schema",
            "default": {},
            "additionalProperties": true,
            "properties": {
              "processEvents": {
                "$id": "#processEvents",
                "type": "object",
                "title": "The processEvents schema",
                "default": {},
                "required": [
                  "identityTrigger"
                ],
                "additionalProperties": true,
                "properties": {
                  "identityTrigger": {
                    "$id": "#identityTrigger",
                    "type": "string",
                    "title": "The identityTrigger schema",
                    "default": ""
                  }
                }
              }
            }
          }
        ],
        "$id": "#items"
      }
    }
  }
}

我要验证的 JSON 是:

{
  "description": "description",
  "requesteeName": "05300005",
  "processOrder": [
  {"cleanHistory": {} },
    {"processEvents": {
      "identityTrigger": "some trigger"
    }}
  ],
  "deleteObjects": "true"
}

现在,我希望当我删除字符串时它会失败:

"identityTrigger": "some trigger"

因为 "identityTrigger" 属性位于 processEvents 对象的所需数组中。但它并没有失败,数组匹配(processOrder 数组)中一定有问题。 有人可以给我一个建议吗? 谢谢

【问题讨论】:

  • 如果您删除“identityTrigger”属性,该 JSON 示例仍会针对第一个 anyOf 选项进行验证,因为它没有定义任何必需的属性。
  • @Carsten 好的,但是当在 processOrder 元素中我有没有 eventTrigger 属性的 processEvent 对象时,我应该如何设置架构以使其失败?

标签: json jsonschema json-schema-validator


【解决方案1】:

验证仍然成功的原因是第一个anyOf 选项没有指定任何required 属性,同时允许任何additionalProperties,因此空的JSON 对象对于第一个选项始终有效。 解决方法是期望每个 anyOf 中至少有一个属性,以避免空对象对它们中的任何一个都有效。

但是,这里似乎还有一些额外的点可以从澄清中受益:

  1. additionalProperties 关键字默认为true,在这种情况下不需要提及。根据json-schema.org

    additionalProperties 关键字用于控制额外内容的处理,即名称未在properties 关键字中列出的属性。默认情况下允许任何其他属性。

  2. additionalItems 关键字仅适用于items 是数组(即数组是特定位置的不同类型的元组)的情况。根据json-schema.org

    items 为单一模式时,additionalItems 关键字无意义,不宜使用。

  3. 您的default 值是空对象,对于具有required 属性的描述结构无效。最好同时保留那些 default 值 - 除非这仅仅是因为您在此问题范围内删除了它们的内容以保持简单。

【讨论】:

    【解决方案2】:

    我已经设法更好地理解它是如何工作的,正如@Carsten 在评论中所说,带有没有必需属性的单个项目的 anyOf 不起作用,因为任何具有任何属性的项目都将被验证。 正确的架构是(以粗体表示的更改):

    {
      "$schema": "http://json-schema.org/draft-07/schema",
      "$id": "urn:jsonschema:testing:frmwk",
      "type": "object",
      "title": "The root schema",
      "default": {},
      "required": [
        "processOrder"
      ],
      "additionalProperties": true,
      "properties": {
        "processOrder": {
          "$id": "#processOrder",
          "type": "array",
          "title": "The processOrder schema",
          "default": [],
          "additionalItems": false,
          "items": {
            "anyOf": [
              {
                "$id": "#0",
                "type": "object",
                "title": "The first anyOf schema",
                "default": {},
                "additionalProperties": true,
                "required": ["cleanHistory"],
                "properties": {
                  "cleanHistory": {
                    "$id": "#cleanHistory",
                    "type": "object",
                    "title": "The cleanHistory schema",
                    "default": {},
                    "additionalProperties": true,
                    "properties": {}
                  }
                }
              },
              {
                "$id": "#3",
                "type": "object",
                "title": "The fourth anyOf schema",
                "default": {},
                "additionalProperties": true,
                "required": ["processEvents"],
                "properties": {
                  "processEvents": {
                    "$id": "#processEvents",
                    "type": "object",
                    "title": "The processEvents schema",
                    "default": {},
                    "required": [
                      "identityTrigger"
                    ],
                    "additionalProperties": true,
                    "properties": {
                      "identityTrigger": {
                        "$id": "#identityTrigger",
                        "type": "string",
                        "title": "The identityTrigger schema",
                        "default": ""
                      }
                    }
                  }
                }
              }
            ],
            "$id": "#items"
          }
        }
      }
    }
    

    主要变化有2个:

    1. 在数组对象定义中添加了 "additionalItems": false
    2. 为每个对应的根属性项添加了 "required": ["cleanHistory"]"required": ["processEvents"],在我的例子中("cleanHistory " 和 "processEvents") 这样,AnyOf 将强制使用列出的架构之一来验证数组中的项目。

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 2015-10-24
      • 1970-01-01
      • 2021-10-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 1970-01-01
      • 2012-07-28
      相关资源
      最近更新 更多