0

my problem statement is : consider a a list of 15 rows, all rows should have 5 keys. However only the 0th row will have 4 keys. But all the remaining rows will have all the 5 keys.

I want to validate this again my response. Does first and other keyword really exist.

I found this here Correct JSON Schema for an array of items of different type

Example schema

{
"type": "array",
"items": {
    "oneOf": [
        {
            "first": [{
                "type": "object",
                "required": ["state"],
                "properties":{
                    "state":{
                        "type":"string"
                    }
                }
            }]
        }, 

        {   
            "other": [{
                "type": "object",
                "required": ["state", "zip"],
                "properties":{
                    "state":{
                        "type":"string"
                    },

                    "zip":{
                        "type":"string"
                    }
                }
            }]
        }
    ]
}  

}

1 Answers1

0

First things first: what do you want to achieve with following schema definition?

"first" : [ { ...schema... } ]

As to your problem statement, I am not sure, what you want to achieve:

  1. Schema that allows first array item to be an object with 4 keys, while all other items should have 5 keys?

  2. Schema, that allows only array items=object with 5 keys and will reject a JSON, which does have 4 keys in first item

Could you please rephrase your question to make it more clear? I did some solution basing on assumptions, but it would be good if you could confirm my understanding.

Required reading

Please read first through:

http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.4.1

If "items" is an array of schemas, validation succeeds if each element of the instance validates against the schema at the same position, if any.

plus https://stackoverflow.com/a/52758108/2811843 on above topic

https://json-schema.org/understanding-json-schema/reference/array.html#length

https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation

and https://json-schema.org/understanding-json-schema/reference/array.html in general

as well as

https://json-schema.org/understanding-json-schema/reference/object.html#property-names

https://json-schema.org/understanding-json-schema/reference/object.html#size

and https://json-schema.org/understanding-json-schema/reference/object.html in general.

Possible solution

After looking at sample schema I will rephrase problem statement making some wild assumptions you want a schema, that allows an array of items, where item = object. First item could have 4 keys, while all other items must have 5 keys.

I need a JSON schema that will describe an array of objects, where first object always has 4 keys/properties, while all remaining objects do have 5 keys/properties.

Additionally, there is always at least first item in array (containing 4 keys) and there can be up to X other objects (containing 5 keys) in array.

Go for Tuple-typing and array of objects. Thus you might exactly check that first item (object) has exactly 4 properties and define the schema for the rest of them.

First, full working schema (with comments inside). The "examples" section contains examples of arrays to illustrate the logic, only last 3 will be valid against schema.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "$comment" : "This is an array, where first item must be an object with at least 4 properties and one property named \"state\" and can contain minimum 1 and maximum of 3 items",
  "minItems" : 1,
  "maxItems" : 3,
  "items": [
    {
      "type": "object",
      "minProperties" : 4,
      "required" : ["state"],      
    }
  ],
  "additionalItems" : {
    "$comment" : "Any additional item in this array must be an object with at least 5 keys and two of them must be \"state\" and \"zip\".",
    "type" : "object",
    "minProperties" : 5,
    "required" : ["state", "zip"],
  },
  "examples" : [
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
      {},
      {}
    ],
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "12345"
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      }
    ],
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "12345"
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "54321"
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "54321"  
      }
    ],
    [],
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "12345"
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "54321"
      },
    ],
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
    ],
    [
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
      },
      {
        "key1" : "1",
        "key2" : "2",
        "key3" : "3",
        "state" : "some state",
        "zip" : "12345"
      },
    ]
  ]
}

So, step by step:

"type": "array",
"minItems" : 1,
"maxItems" : 3,

an JSON which is an array with minimum 1 item, maximum 3 items, will be ok. If you don't define "minItems" value, the empty array would pass validation against schema.

  "items": [
    {
      "type": "object",
      "minProperties" : 4,
      "required" : ["state"],      
    }
  ],

This is the Tuple magic - a finite, ordered list of elements (sequence). Yep, maths has it's saying. By using "items" : [ ... ] instead of { ... } you fall into quoted above section of JSON Schema Validation spec (http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.4.1 ).

Above basically says: This is an array, where first item must be an object with at least 4 keys and one of those keys must be "state".

Ok, last but not least:

  "additionalItems" : {
    "$comment" : "Any additional item in this array must be an object with at least 5 keys and two of them must be \"state\" and \"zip\".",
    "type" : "object",
    "minProperties" : 5,
    "required" : ["state", "zip"],
  }

By this I said: in this array (which must have first item an object with 4 keys and one of those keys is "state" and oh, by the way, an array must have at least 1 item and tops 3 items) you can have additional items on top of the the ones already defined in "items" section. Each such additional item must be an object with at least 5 keys, out of which two must be "state" and "zip".

Does it solve your issue?

PsychoFish
  • 1,541
  • 12
  • 11