I would like to create a recursive schema, where I allow for arbitrary keys inside a nested structure. Basic schema is this:
{
"type": "object",
"properties": {
"Age": {
"type": "number"
},
"Name": {
"type": "string"
}
},
"patternProperties": {
".*": {
"$ref": "#"
}
},
"additionalProperties": false
}
Now I can insert arbitrary keys mapping to a value, which adheres to the same schema again. Now the problem: I need to enforce that both Age and Name are present in every deepest object, by either being directly contained, or being contained in a parent. Valids:
{
"level1": {
"level2": {
"Age": 20,
"Name": "test"
}
}
}
{
"level1": {
"level2": {
},
"Age": 20
},
"Name": "test"
}
{
"level1": {
"level2": {
"Age": 20
}
},
"Name": "test"
}
{
"level1": {
"level2": {
"Age": 20
}
},
"level3": {
"Age": 10
},
"Name": "test"
}
Invalid
{
"level1": {
"level2": {
"Age": 20
}
},
"level3": {
"Name": "test2"
},
"Name": "test"
}
Because the level3 object has no "Age" in itself or in a parent.
How to check for "If I am the deepest object, is somefield contained in me or in any of my ancestors"?
Short background: The json should be used as a configuration file, where multiple concrete configurations can be inserted. I would like the user to be able to simply insert common parameters into higher layers from which they will be cascaded into the concrete configurations.
The problem is that your patternProperties
.*
is also catching Age
and Name
. In order to continue using patternProperties
, you'll need to exclude those from the regex.
Better yet, just drop the patternProperties
and put your $ref
subschema in additionalProperties
, which accepts schemas.
{
"type": "object",
"properties": {
"Age": {
"type": "number"
},
"Name": {
"type": "string"
}
},
"additionalProperties": {
"$ref": "#"
}
}
How to check for "If I am the deepest object, is somefield contained in me or in any of my ancestors"?
I don't think this is possible with JSON Schema.
Each subschema can only look at the current insurance location, not ancestors. You'd need figure out a way to check at the parent level to see if a child contains Age
. I'm not sure how to do that either.