I am having trouble coming up with a JSON schema that will validate if the JSON contains either:
but not to match when multiples of those are present.
In my case specifically, I want one of
copyAll
fileNames
matchesFiles
and/or doesntMatchFiles
to validate but I don't want to accept when more than that is there.
Here's what I've got so far:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [ "unrelatedA" ],
"properties": {
"unrelatedA": {
"type": "string"
},
"fileNames": {
"type": "array"
},
"copyAll": {
"type": "boolean"
},
"matchesFiles": {
"type": "array"
},
"doesntMatchFiles": {
"type": "array"
}
},
"oneOf": [
{"required": ["copyAll"], "not":{"required":["matchesFiles"]}, "not":{"required":["doesntMatchFiles"]}, "not":{"required":["fileNames"]}},
{"required": ["fileNames"], "not":{"required":["matchesFiles"]}, "not":{"required":["doesntMatchFiles"]}, "not":{"required":["copyAll"]}},
{"anyOf": [
{"required": ["matchesFiles"], "not":{"required":["copyAll"]}, "not":{"required":["fileNames"]}},
{"required": ["doesntMatchFiles"], "not":{"required":["copyAll"]}, "not":{"required":["fileNames"]}}]}
]
} ;
This matches more than I want to. I want this to match all of the following:
{"copyAll": true, "unrelatedA":"xxx"}
{"fileNames": ["aab", "cab"], "unrelatedA":"xxx"}
{"matchesFiles": ["a*"], "unrelatedA":"xxx"}
{"doesntMatchFiles": ["a*"], "unrelatedA":"xxx"}
{"matchesFiles": ["a*"], "doesntMatchFiles": ["*b"], "unrelatedA":"xxx"}
but not to match:
{"copyAll": true, "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"fileNames": ["a"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"copyAll": true, "doesntMatchFiles": ["*b"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"fileNames": ["a"], "matchesFiles":["a*"], "unrelatedA":"xxx"}
{"unrelatedA":"xxx"}
I'm guessing there's something obvious I'm missing - I'd like to know what it is.
The problem is the "not" semantics. "not required" does not mean "inclusion forbidden". It just means that you don't have to add it in order to validate that schema.
However, you can use "oneOf" to satisfy your specification in a simpler way. Remember that it means that "just one of these schemas can validate". The following schema achieves the property switching you are attempting to solve:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": [
"unrelatedA"
],
"properties": {
"unrelatedA": {
"type": "string"
},
"fileNames": {
"type": "array"
},
"copyAll": {
"type": "boolean"
},
"matchesFiles": {
"type": "array"
},
"doesntMatchFiles": {
"type": "array"
}
},
"oneOf": [
{
"required": [
"copyAll"
]
},
{
"required": [
"fileNames"
]
},
{
"anyOf": [
{
"required": [
"matchesFiles"
]
},
{
"required": [
"doesntMatchFiles"
]
}
]
}
]
}