Hi Michael,
I just ran into the use case as well and discovered a rather elegant solution using 'not' and 'required'. This avoids duplicating the definitions of the properties and is also scalable to mutual exclusivity with regard to multiple pairs of properties.
The following schema has these conditions:
- 5 defined propertes: a1, a2, b, c1, c2
- b is always required
- a1 and a2 are mutually exclusive, either a1 or a2 must be present
- c1 and c2 cannot both be specified, but they can both be omitted
{
"type": "object",
"properties": {
"a1": { "type": "number" },
"a2": { "type": "number" },
"b": { "type": "string" },
"c1": { "type": "string" },
"c2": { "type": "string" }
},
"additionalProperties": false,
"required": [ "b" ],
"allOf": [
{
"not": {
"type": "object",
"required": [ "a1", "a2" ]
}
},
{
"oneOf": [
{
"type": "object",
"required": [ "a1" ]
},
{
"type": "object",
"required": [ "a2" ]
}
]
},
{
"not": {
"type": "object",
"required": [ "c1", "c2" ]
}
}
]