skip to Main Content

I am trying to write Json schema to validate json file with following content:

{
"number" : "1",
"rootProperty":
[
{
"property1":"value1"
},
{
"property2":"value2"
}
] }

The schema should handle following scenarios:

  1. If property2 is present and property1 is missing, error should be reported mentioning that property1 is missing since its mandatory.
  2. If property1 is present and property2 is missing, error should be reported mentioning that property2 is missing since its mandatory.
  3. No error should be reported if both property1 and property2 are present.
  4. No error should be reported if property2 is mentioned first and then property1 is mentioned.
  5. Error should be reported if any property other than property1 and property2 is mentioned(additionalProperties:false?)
  6. property1 and property2 should not be repeated(uniqueItems:true?)

Could someone please assist?

Also, whether schema is the right way to handle this depth of validation?

When I tried using "items" keyword for the rootProperty array and mentioned property1 and property2 inside required condition, these conditions are evaluated for every element of the array, which results in error saying property2 is missing in first element and property1 is missing in second element.
Also, using "contains" results in error saying object contains property that couldnt be evaluated against any property or additionalProperties.

2

Answers


  1. To validate properties inside an array using JSON Schema, you can use the contains and minContains keywords to ensure the presence of both property1 and property2 at least once. Here’s a schema that should meet your requirements:

    json

    {
      "type": "object",
      "properties": {
        "number": { "type": "string" },
        "rootProperty": {
          "type": "array",
          "items": { "type": "object" },
          "contains": [
            { "required": ["property1"] },
            { "required": ["property2"] }
          ],
          "minContains": 2,
          "additionalProperties": false,
          "uniqueItems": true
        }
      },
      "required": ["number", "rootProperty"]
    }
    
    Login or Signup to reply.
  2. Here’s what I got to work:

    {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "type": "object",
      "properties": {
        "number": { "type": "string" },
        "rootProperty": {
          "type": "array",
          "items": {
            "type": "object",
            "oneOf": [
              { "required": ["property1"] },
              { "required": ["property2"] }
            ]
          },
          "allOf": [
            {
              "contains": { "required": ["property1"] },
              "maxContains": 1
            },
            {
              "contains": { "required": ["property2"] },
              "maxContains": 1
            }
          ] 
        }
      },
      "required": ["number", "rootProperty"]
    }
    

    This works in multiple parts:

    • rootProperty is defined to be an array where all of the items must have either a property1 or a property2 but not both (defined via the oneOf with the required subschemas).
    • Later, defined on the array, we include an allOf with contains subschemas. This means that all of the subschemas must pass, and each subschema says that the array must contain an object with a specific property. The maxContains ensures that only one object in the array contains that property.

    But there is a catch:

    maxContains wasn’t defined until 2019-09, so you’ll need to use that or 2020-12 to make this work. (You mentioned draft 7 in your comment to Tony. I’m afraid you’re not going to be able to make this work with draft 7.)

    Feel free to test this using my online validator: https://json-everything.net/json-schema.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search