JSON Schema Conditional Statements

╄→гoц情女王★ 提交于 2020-12-07 16:29:17

问题


I am trying to validate what I thought was a simple JSON schema as a configuration file for my Python application, it's a list of header key/value pairs, the only complication is that if the 'Type' field is set to 'AnyValue' then the value key is not required.

Here is the schema as it is:

{
    "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']
}

Most of the validation works, except if I add extra values, even though I have set "additionalProperties": false throughout the schema.

Here is an example where extra values are accepted:

{
    "Keys": [

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

Please can someone help explain where I have gone wrong and how I should correct it, please?


回答1:


additionalProperties draft-07...

Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", and do not match any regular expression in "patternProperties".

This means that additionalProperties is only aware of keywords which appear in properties or that match the regex from patternProperties. Using additionalProperties with required without properties is going to create a dud schema (nothing will pass validation).

In stead, you can separate the concerns into what you actually want...

  • You want type, key, and value, to all be strings. One of...
  • If type is AnyValue, then require type and key only.
  • If type is ExactValue, then require type, key, and value.

This is also easier to understand. Here's a 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"
  ]
}


来源:https://stackoverflow.com/questions/58928079/json-schema-conditional-statements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!