0
votes

Here is my JSON schema and JSON as shown below at the bottom and using ajv validator to support json spec draft 7.

By default, the 'science' object must be represented as:

//Default science object
{"type": "science", "rule": {"sciencePattern": {}}}

where the 'rule' and 'sciencePattern' MUST be there.

However, if the 'sciencePattern' about to contains other attributes (as per the schema), then the below validation should kick in:

  1. If the default science object is present, then the "scored" attributes in "arts" object should be REQUIRED.
  2. If the NESTED "scored" array attribute is present within rule as:
{ "type": "science", "rule":{"sciencePattern":{"marks":{"scored":[10]}}} }

then the "scored" attributes in "arts" object should not be REQUIRED. In other words, if some one specify "scored" attribute withn the "arts" object, the schema validation should complain as there is a "scored" attribute is available in "science" object.

//JSON Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "exam"
  ],
  "properties": {
    "exam": {
      "type": "array",
      "minItems": 1,
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/science"
          },
          {
            "$ref": "#/definitions/arts"
          }
        ]
      }
    },
    "if": {
      "type": "object",
      "required": [
        "type",
        "rule"
      ],
      "properties": {
        "type": {
          "const": "science"
        },
        "rule": {
          "type": "object",
          "required": [
            "sciencePattern"
          ],
          "properties": {
            "sciencePattern": {
              "$ref": "#/definitions/sciencePattern"
            }
          }
        }
      }
    },
    "then": {
      "type": "object",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "arts"
        },
        "not": {
          "required": [
            "scored"
          ]
        }
      }
    }
  },
  "definitions": {
    "sciencePattern": {
      "type": "object",
      "required": [
        "marks"
      ],
      "properties": {
        "marks": {
          "type": "object",
          "required": [
            "scored"
          ],
          "properties": {
            "scored": {
              "type": "array"
            }
          }
        }
      }
    },
    "science": {
      "type": "object",
      "properties": {
        "type": {
          "const": "science"
        },
        "rule": {
          "required": [
            "sciencePattern"
          ],
          "properties": {
            "sciencePattern": {
              "$ref": "#/definitions/sciencePattern"
            }
          }
        }
      }
    },
    "arts": {
      "required": [
        "scored"
      ],
      "properties": {
        "type": {
          "const": "arts"
        },
        "scored": {
          "type": "number"
        },
        "remarks": {
          "type": "string"
        }
      }
    }
  }
}

and My JSON

{
  "exam": [
    {
      "type": "science",
      "rule": {
        "sciencePattern": {
          "marks": {
            "scored": [10]
          }
        }
      }
    },
    {
      "type": "arts",
      "scored": 10 //This should complain as 'scored' is available above in science
    }
  ]
}
1
Here, I have updated the schema under "EDIT 1" section. However it still complains if I add "scored" attribute in "arts" object. Any pointers?user8479984
Finally, I have made it and the schema validation is working as expected. See the below section. Thanks.user8479984

1 Answers

0
votes
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "exam"
  ],
  "properties": {
    "exam": {
      "type": "array",     

      "allOf":[      
      {
        "if": {
          "contains": {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "const": "science"
              }            
            }
          }
        },
        "then":{
          "required":["rule", "sciencePattern"]
        }
      },
      {      
        "if": {
          "contains": {
            "type": "object",
            "required":["type","rule", "sciencePattern"],
            "properties": {
              "type": {
                "const": "science"
              }            
            }
          }
        },
        "then":{
          "required":["scored"]
        }
      },
      { 

        "if": {
          "contains": {
            "type": "object",
            "required": [
              "type",
              "rule"
            ],
            "properties": {
              "type": {
                "const": "science"
              },
              "rule": {
                "type": "object",
                "required": [
                  "sciencePattern"
                ],
                "properties": {
                  "sciencePattern": {
                    "$ref": "#/definitions/emptySciencePattern"
                  }
                }
              }
            }
          }
        },
        "then": {
          "contains": {
            "type": "object",
            "required": ["type", "scored"],
            "properties": {
              "type": {
                "const": "arts"
              }
            }
          }
        },
        "else": {
          "if": {
            "contains": {
              "type": "object",
              "required": [
                "type",
                "rule"
              ],
              "properties": {
                "type": {
                  "const": "science"
                },
                "rule": {
                  "type": "object",
                  "required": [
                    "sciencePattern"
                  ],
                  "properties": {
                    "sciencePattern": {
                      "$ref": "#/definitions/sciencePattern"
                    }
                  }
                }
              }
            }
          },
          "then": {
            "contains": {
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "arts"
                }
              },
              "not": {
                "required": ["scored"]
              }
            }
          }
        }
      }],
      "minItems": 1,
      "items": {
        "anyOf": [{
          "$ref": "#/definitions/science"
        }, {
          "$ref": "#/definitions/arts"
        }]
      }
    }
  },
  "definitions": {
    "rule": {
        "type": "object",
        "required": ["sciencePattern"],
        "properties": {
            "sciencePattern": {
                "$ref": "#/definitions/sciencePattern"
            }
        }
    },
    "emptySciencePattern": {
      "type": "object",
      "maxProperties": 0,
      "additionalProperties": false,
      "properties": {}
    },
    "sciencePattern": {
      "type": "object",
      "properties": {
        "marks": {
          "type": "object",
          "properties": {
            "scored": {
              "type": "array"
            }
          }
        }
      }
    },
    "science": {
      "type": "object",
      "required": ["rule"],
      "properties": {
        "type": {
          "const": "science"
        },
        "rule": {
          "$ref":"#/definitions/rule"
        }
      } 
    },
    "arts": {
      "properties": {
        "type": {
          "const": "arts"
        },
        "scored": {
          "type": "number"
        },
        "remarks": {
          "type": "string"
        }
      }
    }
  }
}