json schema - элементы родительского массива (массив объектов) имеют внутренний массив (массив примитивов) с заданными значениями - PullRequest
0 голосов
/ 09 мая 2018

Пожалуйста, не стесняйтесь обновлять название заголовка для этого вопроса.

Я пытаюсь достичь чего-то вроде этого . Входной JSON / данные JSON должны иметь OWNER и учетную запись CHARGE_TO, но они не обязательно должны быть в одной учетной записи (т. Е. Одна учетная запись может быть OWNER, другая может быть CHARGE_TO) и не должна содержать учетную запись с какими-либо другими ролями.

ПРИМЕЧАНИЕ: Необходимо определить схему JSON, которая должна быть простой в обслуживании. Т.е. должно быть легко добавить новую роль в условие. Мои действительные и недействительные JSON:

*************************** VALID JSON1 *********************************
{
  "user": [
    {
      "name": "user1",
      "roles": ["OWNER"]
    },
    {
      "name": "user2",
      "roles": ["ANY_OTHER_ROLE"]
    },
    {
      "name": "user3",
      "roles": ["CHARGE_TO"]
    }]  
}
*************************** VALID JSON2 *********************************
{
  "user": [
    {
      "name": "user1",
      "roles": ["OWNER", "CHARGE_TO"]
    },
    {
      "name": "user2",
      "roles": ["ANY_OTHER_ROLE"]
    }]  
}
*************************** INVALID JSON *********************************
{
  "user": [
    {
      "name": "user1",
      "roles": ["OWNER"]
    },
    {
      "name": "user2",
      "roles": ["ANY_OTHER_ROLE"]
    }]  
}

JSON действителен, если у него есть пользователь с ролями ( "OWNER" и "CHARGE_TO" ) или если пользователи с ролями ( user1 - "OWNER", user3- "CHARGE_TO", другие пользователи с любой другой ролью ).

Ниже приведена схема JSON, которую я пробовал (draft_07). ЭТО НЕ РАБОЧАЯ СХЕМА .

{
"$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Complex inner array",
  "type": "object",
  "properties": {
    "user": {
      "type": "array",
      "contains": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "orderRoles": {
            "type": "array",
            "minItems": 1,
            "items": { "type": "string" }
          }
        },
        "oneOf": [
          { "properties": { "roles": { "enum": ["OWNER", "CHARGE_TO"] }}},
          { "properties": { "roles": { "enum": ["OWNER"] }}},
          { "properties": { "roles": { "enum": ["CHARGE_TO"] }}}
        ]
      },
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "orderRoles": {
            "type": "array",
            "minItems": 1,
            "items": { "type": "string" }
          }
        }
      }
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вам необходимо изолировать часть схемы, которая проверяет определенную роль. Тогда вы можете просто объединить их с allOf. Дублирование как можно меньше, и вы можете легко добавить еще одно ограничение.

{
  "type": "object",
  "properties": {
    "user": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "roles": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      },
      "allOf": [
        { "$ref": "#/definitions/require-role-owner" },
        { "$ref": "#/definitions/require-role-charge-to" }
      ]
    }
  },
  "definitions": {
    "require-role-owner": {
      "contains": {
        "properties": {
          "roles": {
            "contains": { "const": "OWNER" },
            "allOf": [{ "$ref": "#/definitions/not-other-role" }]
          }
        }
      }
    },
    "require-role-charge-to": {
      "contains": {
        "properties": {
          "roles": {
            "contains": { "const": "CHARGE_TO" },
            "allOf": [{ "$ref": "#/definitions/not-other-role" }]
          }
        }
      }
    },
    "not-other-role": {
      "items": { "enum": ["OWNER", "CHARGE_TO"] }
    }
  }
}
0 голосов
/ 10 мая 2018

Ниже моя рабочая схема. Это не элегантное решение, поскольку схема становится огромной, если добавляется новая роль («ADMIN»), то есть условие схемы будет An input JSON/data JSON must have an OWNER, ADMIN and a CHARGE_TO Account, but these don't have to be on the same Account (I.e. one Account can be OWNER, one Account can be ADMIN & another can be CHARGE_TO) and must not contain account with any other roles. Пожалуйста, не стесняйтесь улучшить это. Благодаря.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Complex inner array",
  "type": "object",
  "allOf": [
    {
      "properties": {
        "account": {
          "type": "array",
          "contains": {
            "type": "object",
            "properties": {
              "roles": {
                "type": "array",
                "minItems": 1,
                "contains": { "enum": ["OWNER"] }
              }
            }
          }
        }
      }
    },
    {
      "properties": {
        "account": {
          "type": "array",
          "contains": {
            "type": "object",
            "properties": {
              "roles": {
                "type": "array",
                "minItems": 1,
                "contains": { "enum": ["CHARGE_TO"] }
              }
            }
          }
        }
      }
    },
    {
      "properties": {
        "account": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "roles": {
                "type": "array",
                "minItems": 1,
                "items":{
                  "enum": ["CHARGE_TO", "OWNER"]
                }
              }
            }
          }
        }
      }
    }
  ]
}
...