Reposting the question How to implement conditional nested properties with JSON Schema (marked as duplicate though its a completely different problem) My JSON schema reads below tried based on : JSON Schema if/then require nested object
{
"$id": "myschema.json",
"if":{
"type":"object",
"properties": {
"common_data": {
"type":"object",
"properties":{
"remote_os": {
"type":"object",
"required":["common_data"],
"const": "Linux"
}
},
"required":["remote_os"]
}
}
},
"then": {
"type":"object",
"properties": {
"file": {
"type": "string",
"pattern": "^(.*.)(bin)$"
}
}
},
"else": {
"type":"object",
"properties": {
"file": {
"type": "string",
"pattern": "^(.*.)(exe)$"
}
}
}
}
Basically adding the if-else
logic to make sure for remote_os=Linux
file
should end up with .bin
and remote_os=Windows
file
should end up with .exe
Now I am trying to validate against below data
{
"common_data": {
"remote_os": "Linux"
},
"file": "abc.bin"
}
Getting error : [<ValidationError: "'abc.bin' does not match '^(.*.)(exe)$'">]
When tried to debug what properties python
jsonschema
is trying build on top of this schema to validate my data. Got this
properties {'common_data': {'type': 'object', 'properties': {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}, 'required': ['remote_os']}}
properties {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}
properties {'file': {'type': 'string', 'pattern': '^(.*.)(exe)$'}}
So its always matching against the 'pattern': '^(.*.)(exe)$'
irrespective of remote_os
. Looking for some guidance, how to address this issue.
You're close, but there are a few problems.
First, let's assess if our assumption is right... It looks like if
is failing, and triggering the else
schema value to be applied rather than the then
schema value. We can check this by changing if
to simply true
.
Yup, the then
subschema works OK when applied.
OK, so let's remove parts of the nested schema till it works as we expect...
Ah... Look. remote_os
in our data is a string, but it has been defined in the schema as being an object. Remove type: object
.
Those required
keywords don't match the data location... they just need to be moved UP to the correct level...
We end up with this schema: (live demo: https://jsonschema.dev/s/CEwMw)
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "myschema.json",
"if": {
"type": "object",
"required": [
"common_data"
],
"properties": {
"common_data": {
"type": "object",
"required": [
"remote_os"
],
"properties": {
"remote_os": {
"const": "Linux"
}
}
}
}
},
"then": {
"type": "object",
"properties": {
"file": {
"type": "string",
"pattern": "^(.*.)(bin)$"
}
}
},
"else": {
"type": "object",
"properties": {
"file": {
"type": "string",
"pattern": "^(.*.)(exe)$"
}
}
}
}
Further, another schema debugging tip, is take the if
schema value out, and use that as your whole schema. That way you can find out why THAT is failing validation, rather than just guessing.
These are easy mistakes to make! I made a few while trying to fix it. The important thing is to know how to debug your schema. Test assumptions, and recognise subschemas.