I'm working on a JSON schema and I'm stuck on array validations. I have this example input JSON
{
"paths_1": {
"path_1": [
{
"abc": "valid_abc"
},
{
"abc": "invalid_abc"
}
]
},
"paths_2": {
"path_2": [
{
"ghi": "valid_ghi"
}
]
}
}
My rule for this JSON data is, if paths_2.path_2[].ghi
is "valid_ghi" and paths_1.path_1[].abc
is "valid_abc", then require "def" key for the object that has "valid_abc".
I created this JSON schema for this rule, but it doesn't work as expected.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"paths_1": {
"type": "object",
"properties": {
"items": {
"properties": {
"path_1": {
"properties": {
"abc": {
"type": "string"
},
"def": {
"type": "string"
}
}
}
}
}
}
},
"paths_2": {
"type": "object",
"properties": {
"items": {
"properties": {
"path_2": {
"properties": {
"ghi": {
"type": "string"
}
}
}
}
}
}
}
},
"allOf": [
{
"if": {
"allOf": [
{
"properties": {
"paths_1": {
"properties": {
"path_1": {
"contains": {
"properties": {
"abc": {
"const": "valid_abc"
}
},
"required": [
"abc"
]
}
}
}
}
}
},
{
"properties": {
"paths_2": {
"properties": {
"path_2": {
"contains": {
"properties": {
"ghi": {
"const": "valid_ghi"
}
},
"required": [
"ghi"
]
}
}
}
}
}
}
]
},
"then": {
"properties": {
"paths_1": {
"properties": {
"path_1": {
"items": {
"required": [
"def"
]
}
}
}
}
}
}
}
]
}
When I tested this schema, it returns 'def' is a required property for the object with "invalid_abc", when it should not.
I tried changing contains keys to items in JSON schema but in this case, if part becomes false and validator returns that input is valid.
Is there a way to validate this input with the given rule?
CodePudding user response:
You need to check for valid_abc
in items
again.
Your then
clause has no context, which I think is what you're expecting.
"items": {
"if": {
"properties": {
"abc": {
"const": "valid_abc"
}
},
"required": [
"abc"
]
},
"then": {
"required": [
"def"
]
}
}
Demo: https://jsonschema.dev/s/M3cvJ
As a result, you can simplify your conditional checking, as you don't need to check if the array contains an object with valid_abc
. You can remove if/allOf[0]
, and unwrap the allOf
as it will then only have one subschema.