How to write a JSON schema for array of objects?
json, jsonschema, ruby
Solution
From the JSON schema spec, section 5.5. items:
When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST conform to the schema in the corresponding position for this array. This called tuple typing.
Your schema definition requires the first three elements of the array to be exactly those 'a', 'b' and 'c' elements. If `items` is left empty, any array element is allowed. Similarly, if `additionalItems` is left empty, any additional array element is allowed.
To get what you want, you need to specify `"additionalItems": false` and for the `items`, I think the following (somewhat shortened from your definitions) should work:
"items": {
"type": [
{"type":"object", "properties": {"a": {"type": "object", "properties": {"ax": { "type":"number"}}}}},
{"type":"object", "properties": {"b": {"type": "object", "properties": {"bx": { "type":"number"}}}}},
{"type":"object", "properties": {"c": {"type": "object", "properties": {"cx": { "type":"number"}}}}}
]
}
Problem
My JSON string would be formatted as: ``` { "count":3, "data":[ { "a":{"ax":1} }, { "b":{"bx":2} }, { "c":{"cx":4} } ] } ``` The `data` array contains many `a` and `b` and `c`. And no other kinds of objects. If `count==0`, `data` should be an empty array `[]`. I'm using https://github.com/hoxworth/json-schema to validate such JSON objects in Ruby. ``` require 'rubygems' require 'json-schema' p JSON::Validator.fully_validate('schema.json',"test.json") ``` The `schema.json` is: ``` { "type":"object", "$schema": "http://json-schema.org/draft-03/schema", "required":true, "properties":{ "count": { "type":"number", "id": "count", "required":true }, "data": { "type":"array", "id": "data", "required":true, "items":[ { "type":"object", "required":false, "properties":{ "a": { "type":"object", "id": "a", "required":true, "properties":{ "ax": { "type":"number", "id": "ax", "required":true } } } } }, { "type":"object", "required":false, "properties":{ "b": { "type":"object", "id": "b", "required":true, "properties":{ "bx": { "type":"number", "id": "bx", "required":true } } } } }, { "type":"object", "required":false, "properties":{ "c": { "type":"object", "id": "c", "required":true, "properties":{ "cx": { "type":"number", "id": "cx", "required":true } } } } } ] } } } ``` But this for `test.json` will pass the validation while I suppose it should fail: ``` { "count":3, "data":[ { "a":{"ax":1} }, { "b":{"bx":2} }, { "c":{"cx":2} }, { "c": {"z":"aa"} } ] } ``` And this as `test.json` will fail, while I suppose it should pass: ``` { "count":3, "data":[ { "a":{"ax":1} }, { "b":{"bx":2} } ] } ``` Seems the wrong schema is validating that the `data` array contains `a,b,c` once. What the right schema should be?