Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a JSON schema for array of objects?

Tags:

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?

like image 858
Green Su Avatar asked May 30 '12 03:05

Green Su


People also ask

How do you represent an array of objects in JSON?

A JSON array contains zero, one, or more ordered elements, separated by a comma. The JSON array is surrounded by square brackets [ ] . A JSON array is zero terminated, the first index of the array is zero (0). Therefore, the last index of the array is length - 1.

Can you have an array of JSON objects?

Yes, you can create an array of objects. Technically, a 2D array is valid JSON. In fact, pretty much any object that doesn't have special abilities (ie. DOM objects and things like new Date() and new Image() ) could qualify as JSON.

What is a schema array?

Array Schemas Arrays are used to represent ordered sets of values, such as the following sequence of strings: ["Chilean", "Argentinean", "Peruvian", "Colombian"] In this section we specify array's main charasteristics and restrictions that may apply to them using a single JSON Schema document.

How do I set a schema in JSON?

At the top of the file, you can specify the schema's id, the schema that should be used to validate the format of your schema, and a descriptive title. These are all defined using the keywords id, $schema and title, all of which are provided in the draft JSON Schema.


1 Answers

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"}}}}}   ] } 
like image 139
Confusion Avatar answered Oct 22 '22 03:10

Confusion