Подтвердить что ты не робот

Как написать схему JSON для массива объектов?

Моя строка JSON будет отформатирована как:

{
    "count":3,
    "data":[
        {
            "a":{"ax":1}
        },
        {
            "b":{"bx":2}
        },
        {
            "c":{"cx":4}
        }
    ]
}

Массив data содержит много a и b и c. И никаких других видов объектов.

Если count==0, data должен быть пустым массивом [].

Я использую https://github.com/hoxworth/json-schema для проверки таких объектов JSON в Ruby.

require 'rubygems'
require 'json-schema'

p JSON::Validator.fully_validate('schema.json',"test.json")

schema.json:

{
  "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 } } } } }
       ]
     }
  }
}

Но это для test.json будет проходить проверку, пока я предполагаю, что он должен потерпеть неудачу:

{
  "count":3,
  "data":[
      {
          "a":{"ax":1}
      },
      {
          "b":{"bx":2}
      },
      {
          "c":{"cx":2}
      },
      {
          "c": {"z":"aa"}
      }
   ]
}

И это как test.json не удастся, хотя я предполагаю, что он должен пройти:

{
  "count":3,
  "data":[
      {
          "a":{"ax":1}
      },
      {
          "b":{"bx":2}
      }
   ]
}

Кажется, неправильная схема проверяет, что массив data содержит a,b,c один раз.

Какая должна быть правильная схема?

4b9b3361

Ответ 1

Из спецификации схемы JSON, раздел 5.5. пункты:

Когда это значение атрибута представляет собой массив схем, а экземпляр - value - массив, каждая позиция в массиве экземпляров ДОЛЖНА соответствовать к схеме в соответствующей позиции для этого массива. Это
так называемый набор кортежей.

Определение вашей схемы требует, чтобы первые три элемента массива были точными элементами "a", "b" и "c". Если items оставлено пустым, разрешен любой элемент массива. Аналогично, если additionalItems остается пустым, допускается любой дополнительный элемент массива.

Чтобы получить то, что вы хотите, вам нужно указать "additionalItems": false и для items, я думаю, что следующее (несколько сокращенное из ваших определений) должно работать:

"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"}}}}}
  ]
}