Схема JSON, если вложенная - PullRequest
0 голосов
/ 29 марта 2019

Кажется, я не могу найти работающий способ применения логики if / then к перечислению.

anyOf не применяет условную логику, а вместо этого говорит, что если какой-либо из них соответствует, то это хорошо.

allOf снова не применяет условную логику, но проверяет расширенный набор свойств / обязательных полей.

Вот пример схемы JSON:

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "type"
  ],
  "properties": {
    "type": {
      "$id": "#/properties/type",
      "enum": [
        "a",
        "b",
        "c"
      ],
      "title": "The Type"
    },
    "options": {
      "$id": "#/properties/options",
      "type": "object",
      "title": "The Options Schema",
      "oneOf": [
        {
          "if": { "properties": { "type": { "const": "a" } }
          },
          "then": {
            "required": [ "option1" ],
            "properties": {
              "option1": {
                "$id": "#/properties/options/properties/option1",
                "type": "boolean",
                "title": "The option1 Schema"
              }
            }
          }
        },
        {
          "if": { "properties": { "type": { "const": "b" } }
          },
          "then": {
            "required": [ "option2" ],
            "properties": {
              "option2": {
                "$id": "#/properties/options/properties/option2",
                "type": "boolean",
                "title": "The option2 Schema"
              }
            }
          }
        },
        {
          "if": { "properties": { "type": { "const": "c" } }
          },
          "then": {
            "required": [],
            "properties": {}
          }
        }
      ]
    }
  }
}

Если выпроверить по этому JSON:

{
  "type": "a",
  "options": {
    "option1": true
  }
}

Сбой, потому что требуется option2.

Если вы измените его на anyOf, то это будет успешно, но если вы измените JSON на недействительный:

{
  "type": "a",
  "options": {
    "option2": false
  }
}

Это все еще успешно.

Мне не удалось получить вложенность, если / then / else / if / then / else работает либо.

Как мне выполнитьпроверка, где у меня есть набор свойств для каждого type, и вы не можете смешивать их?Это действительно возможно, или я должен просто изменить свой дизайн.

1 Ответ

0 голосов
/ 30 марта 2019

Во-первых, вы можете проверить свои схемы здесь .В Интернете есть несколько таких сайтов.

Во-вторых, была введена конструкция if / then / else, которая заменила oneOf для таких сценариев перечисления, а не объединялась сit.

Эта подсхема

"if": { "properties": { "type": { "const": "a" } } },
"then": {
  "required": [ "option1" ],
  "properties": {
    "option1": {
      "$id": "#/properties/options/properties/option1",
      "type": "boolean",
      "title": "The option1 Schema"
    }
  }
}

на самом деле не дает сбоя, когда type не a.Он просто говорит, что , если type=a, применить подсхему then.Он ничего не говорит о том, что действительно проверяется, если type равно , а не a, поэтому оно проходит.Если вы добавите else:false к этому, это будет более соответствовать тому, что вы думаете, но я призываю вас думать об этом по-другому.

Используйте oneOf или if / then / else, но не оба.Я предлагаю изменить ваши подсхемы, чтобы использовать этот формат:

{
  "properties": {
    "type": { "const": "a" },
    "option1": {
      "$id": "#/properties/options/properties/option1",
      "type": "boolean",
      "title": "The option1 Schema"
    }
  },
  "required": [ "option1" ],
}

Это подтверждает, что option1 является обязательным и должно быть логическим, а type=a.Если type равно , а не a, эта схема завершится ошибкой, что вам и нужно.

Этот ответ описывает, что вам нужно сделать, немного большеподробно.

...