So I had this json
{
"f1":"John",
"f2":"whatever",
"f3":"abc"
}
I wanted to validate it as only one of f1
, f2
, f3
should be present. If neither f1
, f2
and f3
are present then it should pass.
Something like,
{
"f1":"John",
}
PASS
{
"f1":"John",
"f2":"whatever",
}
FAIL
{
"f1":"John",
"f2":"whatever",
"f3":"abc"
}
FAIL
{}
PASS
Here is the code I wrote but it is failing
{
"allOf": [
{
"if": {
"required": [
"f1"
]
},
"then": {
"not": {
"required": [
"f2", "f3"
]
}
}
},
{
"if": {
"required": [
"f3"
]
},
"then": {
"not": {
"required": [
"f2", "f1"
]
}
}
},
{
"if": {
"required": [
"f2"
]
},
"then": {
"not": {
"required": [
"f3", "f1"
]
}
}
}
]
}
EDIT: snippet of schema https://jsonschema.dev/s/eN6Db
CodePudding user response:
From your requirements as given, you don't need to check against the other properties as they are defined. A schema like this would be sufficient:
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
"properties": {
"f1": {
"type": "string"
},
"f2": {
"type": "string"
},
"f3": {
"type": "string"
}
},
"minProperties": 0,
"maxProperties": 1,
"additionalProperties": false
}
However, this does not work if you also need other properties at this level.
CodePudding user response:
You have two options here.
You can add else: false
to each of your subschemas (demo)
OR, remove the conditional checks and use oneOf
. You'd have to also add a subschema to allow for empty objects. The second approach may be preferable.
Here's the schema and a demo.
{
"oneOf": [
{
"additionalProperties": false
},
{
"required": [
"f1"
],
"not": {
"required": [
"f2",
"f3"
]
}
},
{
"required": [
"f3"
],
"not": {
"required": [
"f2",
"f1"
]
}
},
{
"required": [
"f2"
],
"not": {
"required": [
"f3",
"f1"
]
}
}
]
}