【问题标题】:JSON Schema Conditional StatementsJSON 模式条件语句
【发布时间】:2019-11-19 06:45:23
【问题描述】:

我正在尝试验证我认为的简单 JSON 模式作为我的 Python 应用程序的配置文件,它是标题键/值对的列表,唯一的复杂之处是如果“类型”字段设置为“ AnyValue' 则不需要 value 键。

这是架构的原样:

{
    "definitions":
    {
        'KeyEntry':
        {
             "properties":
             {
                'Type': {"type" : "string"},
                'Key': {"type": "string"}
             },
             "required": ['Type', 'Key'],
            "anyOf":
            [
                {
                    "if":
                    {
                        "properties": {'Type': {"const": 'ExactValue'}}
                    },
                    "then":
                    {
                        "properties":
                        {
                            'Value': {"type": "string"}
                        },
                        "required": ['Type', 'Key', 'Value'],
                        "additionalProperties": false
                    }
                },
                {
                    "if":
                    {
                        "properties": {'Type': {"const": 'AnyValue'}}
                    },
                    "then":
                    {
                        "required": ['Type', 'Key'],
                        "additionalProperties": false
                    }
                }
            ]
        }
    },

    "type": "object",
    "properties":
    {
        'Keys':
        {
            "type": "array",
            "items": {"$ref": "#/definitions/KeyEntry"}
        }
    },
    "required": ['Keys']
}

大多数验证都有效,除非我添加额外的值,即使我在整个架构中设置了 "additionalProperties": false。

这是一个接受额外值的示例:

{
    "Keys": [

        {
            "Type": "AnyValue",
            "Key": "Version",
            "Y": "Yes",
            "N": "No",
        }
    ]
}

请有人帮忙解释一下我哪里出错了,我应该如何纠正?

【问题讨论】:

  • 啊,这是一个经典的绊脚石。我现在无法完全检查解决方案,但是如果你将 anyOf 更改为 allOf,并在 if 块中添加 else: false 会发生什么?
  • 即使没有帮助,我会尽快提供帮助。 =]
  • @Relequestual 嗨,只要可以到 allOf 的 anyOf,我就会得到 'JSON 不匹配来自 'allOf' 的所有模式。无效的架构索引:1。验证错误,这是在我添加 else 之前 :(

标签: json jsonschema json-schema-validator


【解决方案1】:

additionalProperties draft-07...

使用“additionalProperties”进行验证仅适用于与“properties”中的任何名称不匹配且不匹配“patternProperties”中的任何正则表达式的实例名称的子值。

这意味着additionalProperties 只知道出现在properties 中或匹配来自patternProperties 的正则表达式的关键字。使用 additionalPropertiesrequired 而不使用 properties 将创建一个无效的模式(没有任何东西可以通过验证)。

相反,您可以将关注点分成您真正想要的内容...

  • 您希望类型、键和值都是字符串。 其中之一...
  • 如果类型是 AnyValue,则只需要类型和键。
  • 如果类型为 ExactValue,则需要类型、键和值。

这也更容易理解。这是live demo with your data

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "KeyEntry": {
      "properties": {
        "Type": {
          "type": "string"
        },
        "Key": {
          "type": "string"
        },
        "Value": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": [
        "Type",
        "Key"
      ],
      "anyOf": [
        {
          "if": {
            "properties": {
              "Type": {
                "const": "ExactValue"
              }
            }
          },
          "then": {
            "required": [
              "Type",
              "Key",
              "Value"
            ]
          },
          "else": false
        },
        {
          "if": {
            "properties": {
              "Type": {
                "const": "AnyValue"
              }
            }
          },
          "then": {
            "required": [
              "Type",
              "Key"
            ]
          },
          "else": false
        }
      ]
    }
  },
  "type": "object",
  "properties": {
    "Keys": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/KeyEntry"
      }
    }
  },
  "required": [
    "Keys"
  ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2019-10-05
    • 2012-08-30
    • 1970-01-01
    • 2019-04-29
    • 2013-12-11
    • 2022-01-17
    相关资源
    最近更新 更多