问题
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