如何为对象数组编写JSON模式?

Gre*_* Su 22 ruby json jsonschema

我的JSON字符串格式为:

{
    "count":3,
    "data":[
        {
            "a":{"ax":1}
        },
        {
            "b":{"bx":2}
        },
        {
            "c":{"cx":4}
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

data数组包含许多abc.而且没有其他种类的对象.

如果count==0,data应该是一个空数组[].

我正在使用https://github.com/hoxworth/json-schema来验证Ruby中的这些JSON对象.

require 'rubygems'
require 'json-schema'

p JSON::Validator.fully_validate('schema.json',"test.json")
Run Code Online (Sandbox Code Playgroud)

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 } } } } }
       ]
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是这个test.json将通过验证,而我认为它应该失败:

{
  "count":3,
  "data":[
      {
          "a":{"ax":1}
      },
      {
          "b":{"bx":2}
      },
      {
          "c":{"cx":2}
      },
      {
          "c": {"z":"aa"}
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

test.json将失败,而我认为它应该通过:

{
  "count":3,
  "data":[
      {
          "a":{"ax":1}
      },
      {
          "b":{"bx":2}
      }
   ]
}
Run Code Online (Sandbox Code Playgroud)

似乎错误的模式验证data数组包含a,b,c一次.

什么是正确的架构?

Con*_*ion 30

JSON架构规范,第5.5节.项目:

当此属性值是模式数组且实例
值是数组时,实例数组中的每个位置必须符合
此数组的相应位置中的模式.这
叫做元组打字.

您的模式定义要求数组的前三个元素恰好是'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"}}}}}
  ]
}
Run Code Online (Sandbox Code Playgroud)