web-dev-qa-db-fra.com

Comment écrire un schéma JSON pour un tableau d'objets?

Ma chaîne JSON serait formatée comme suit:

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

Le tableau data contient de nombreux a et b et c. Et pas d'autres types d'objets.

Si count==0, data doit être un tableau vide [].

J'utilise https://github.com/hoxworth/json-schema pour valider ces objets JSON dans Ruby.

require 'rubygems'
require 'json-schema'

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

Le schema.json est:

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

Mais cela pour test.json passera la validation alors que je suppose que cela devrait échouer:

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

Et cela comme test.json échouera, alors que je suppose qu'il devrait passer:

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

Il semble que le mauvais schéma valide que le tableau data contient a,b,c une fois que.

Quel devrait être le bon schéma?

22
Green Su

À partir de spécification de schéma JSON , section 5.5. articles:

Lorsque cette valeur d'attribut est un tableau de schémas et l'instance
La valeur est un tableau, chaque position dans le tableau d'instances DOIT être conforme
au schéma dans la position correspondante pour ce tableau. Ce
appelé Tuple typing.

Votre définition de schéma requiert que les trois premiers éléments du tableau soient exactement les éléments "a", "b" et "c". Si items est laissé vide, tout élément de tableau est autorisé. De même, si additionalItems est laissé vide, tout élément de tableau supplémentaire est autorisé.

Pour obtenir ce que vous voulez, vous devez spécifier "additionalItems": false et pour le items, je pense que ce qui suit (quelque peu raccourci de vos définitions) devrait fonctionner:

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