I have the following JSON Schema:
{
"type": "object",
"additionalProperties": false,
"properties": {
"abc": {
"type": "string"
},
"abc@mandatory": {
"type": "string"
},
"abc@optional": {
"type": "string"
},
"def": {
"type": "string"
},
"def@mandatory": {
"type": "string"
},
"def@optional": {
"type": "string"
}
},
"dependentSchemas": {
"abc": {
"required": [
"abc@mandatory"
]
},
"def": {
"required": [
"def@mandatory"
]
}
}
}
It enforces that the property abc@mandatory
is present if abc
is present. But I want an additional rule saying that neither abc@mandatory
nor abc@optional
must be present if abc
is not present. How can I achieve this?
I generate the JSON schema, and actually there is an arbitrary number of such combinations, for example def
and def@...
.
Background: I want to transform my data into this XML string:
<abc mandatory="foo" optional="bar">Some value</xyz>
The properties containing an @
translate to XML attributes. The attribute mandatory
is a mandatory attribute of abc
and the attribute optional
is an optional attribute of abc
.
However, the element abc
itself is optional and if it is not present, then neither the attribute mandatory
nor optional
makes sense.
I am missing two features in JSON Schema: First, I want to define rules for the case that a certain property is not present. Second, I want to find a way to forbid certain properties. I could achieve the second feature by specifying rules that never evaluate to true
(for example { "minLength": 1, "maxLength": 0 }
) but that would lead to confusing error messages.
If you think that you have an answer to the question, please make sure that the following conditions are met:
Valid data:
{}
{
"abc": "exists",
"abc@mandatory": "exists"
}
{
"def": "exists",
"def@mandatory": "exists"
}
{
"abc": "exists",
"abc@mandatory": "exists",
"def": "exists",
"def@mandatory": "exists"
}
Invalid data:
{
"abc@mandatory": "exists"
}
{
"abc@optional": "exists"
}
{
"abc@mandatory": "exists",
"def": "exists",
"def@mandatory": "exists"
}
... and so on.
Of course, it is possible to provide a schema by enumerating all valid combinations with allOf
, anyOf
, and required
. But that will blow up the schema when more elements ghi
, jk
, ... with their corresponding attributes are added. I prefer a solution, where I can add one single group of conditions for every element and its attributes.
You can use dependentRequired
and list all the possibilities.
edit: This is only valid for JSON Schema 2019-09 or newer
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"properties": {
"abc": {
"type": "string"
},
"abc@mandatory": {
"type": "string"
},
"abc@optional": {
"type": "string"
},
"def": {
"type": "string"
},
"def@mandatory": {
"type": "string"
},
"def@optional": {
"type": "string"
}
},
"dependentRequired": {
"abc": [
"abc@mandatory"
],
"def": [
"def@mandatory"
],
"abc@mandatory": [
"abc"
],
"abc@optional": [
"abc"
]
}
}