I cannot seem to find a working way of applying multiple if/then logic on an enum.
anyOf
doesnt apply the conditional logic, but instead it says if any of them match then thats good.
allOf
again doesnt apply the conditional logic but tests a superset of the properties/required fields.
Here is a JSON Schema example:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"required": [
"type"
],
"properties": {
"type": {
"$id": "#/properties/type",
"enum": [
"a",
"b",
"c"
],
"title": "The Type"
},
"options": {
"$id": "#/properties/options",
"type": "object",
"title": "The Options Schema",
"oneOf": [
{
"if": { "properties": { "type": { "const": "a" } }
},
"then": {
"required": [ "option1" ],
"properties": {
"option1": {
"$id": "#/properties/options/properties/option1",
"type": "boolean",
"title": "The option1 Schema"
}
}
}
},
{
"if": { "properties": { "type": { "const": "b" } }
},
"then": {
"required": [ "option2" ],
"properties": {
"option2": {
"$id": "#/properties/options/properties/option2",
"type": "boolean",
"title": "The option2 Schema"
}
}
}
},
{
"if": { "properties": { "type": { "const": "c" } }
},
"then": {
"required": [],
"properties": {}
}
}
]
}
}
}
If you validate against this JSON:
{
"type": "a",
"options": {
"option1": true
}
}
It fails because option2
is required.
If you change it to anyOf
then it succeeds, but if you change the JSON to be invalid:
{
"type": "a",
"options": {
"option2": false
}
}
It still succeeds.
I havent managed to get nested if/then/else/if/then/else working either.
How can i perform a check where I have set of properties for each type
and you cannot intermingle them? Is this actually possible, or should I just change my design.
First, you can test your schemas here . There are several of these sites across the internet.
Second, the if
/ then
/ else
construct was introduced to replace a oneOf
for these kind of enum scenarios, not be combined with it.
This subschema
"if": { "properties": { "type": { "const": "a" } } },
"then": {
"required": [ "option1" ],
"properties": {
"option1": {
"$id": "#/properties/options/properties/option1",
"type": "boolean",
"title": "The option1 Schema"
}
}
}
doesn't actually fail when type
is not a
. It merely says that if type=a
, apply the then
subschema. It doesn't say anything about what do validate if type
is not a
, so it passes. If you add an else:false
to this, it'll be more in line with what you're thinking, but I encourage you to think about it differently.
Use oneOf
or if
/ then
/ else
, but not both. I suggest changing your subschemas to use this format:
{
"properties": {
"type": { "const": "a" },
"option1": {
"$id": "#/properties/options/properties/option1",
"type": "boolean",
"title": "The option1 Schema"
}
},
"required": [ "option1" ],
}
This asserts that option1
is required and must be a boolean, and that type=a
. If type
is not a
, this schema fails, which is what you want.
This answer describes what you need to do in a bit more detail.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.