Содержание свойства зависит от другого значения свойства - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть следующая схема, которая «работает», но не соблюдает все требуемые правила.

Я получаю JSON с серией вопросов, которые имеют свойства templateType и data .Для каждого типа существуют разные шаблоны, и тип должен соответствовать шаблону (или клиент не знает, как расположить данные).

Схема проверяет templateType как перечислениеи что данные соответствуют одному из шаблонов, но нет корреляции между типом и структурой данных (например, я мог бы получить templateType yesNo и структуру данных для multiSelect).

Я быКак проверить, что templateType соответствует структуре данных.Я не могу изменить формат сгенерированного JSON, только схему, которая его проверяет.Кажется, ни один из вопросов, на которые я смотрел, не дает решения.

Для справки схему можно вставить в редактор по адресу http://jeremydorn.com/json-editor/,, который генерирует форму на основе схемы и данных JSON.на выбор и данные, введенные в форму.

{
  "definitions": {
    "question": {
      "type": "array",
      "title": "Question",
      "items": {
        "$ref": "#/definitions/template"
      }
    },
    "template": {
      "type": "object",
      "title": "Question template",
      "required": ["templateType","data"],
      "properties": {
        "templateType": {
          "type": "string",
          "enum": ["yesNo","multiSelect"]
        },
        "data": {
          "oneOf": [
            {"$ref": "#/definitions/yesNo"},
            {"$ref": "#/definitions/multiSelect"}
          ]
        }
      }
    },
    "yesNo": {
      "type": "object",
      "title": "Yes/No question",
      "additionalProperties": false,
      "properties": {
        "label": {
          "type": "string"
        }
      }
    },
    "multiSelect": {
      "type": "array",
      "title": "Multi-select question",
      "items": {
        "type": "string",
        "title": "Label for option",
        "additionalProperties": false
      }
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "$ref": "#/definitions/question"
  }
}

1 Ответ

0 голосов
/ 28 ноября 2018

Рассматривали ли вы использование if, then, else ключевых слов в вашей схеме?Они являются частью JSON Schema draft-07

Это будет выглядеть так:

{
  "definitions": {
    "question": {
      "type": "array",
      "title": "Question",
      "items": {
        "$ref": "#/definitions/template"
      }
    },
    "template": {
      "type": "object",
      "title": "Question template",
      "required": ["templateType","data"],
      "properties": {
        "templateType": {
          "type": "string",
          "enum": ["yesNo","multiSelect"]
        },
        "data": {
          "if": { "properties": { "templateType": { "pattern": "^yesNo$" } } },
          "then": { "$ref": "#/definitions/yesNo" },
          "else": { "$ref": "#/definitions/multiSelect" }
        }
      }
    },
    "yesNo": {
      "type": "object",
      "title": "Yes/No question",
      "additionalProperties": false,
      "properties": {
        "label": {
          "type": "string"
        }
      }
    },
    "multiSelect": {
      "type": "array",
      "title": "Multi-select question",
      "items": {
        "type": "string",
        "title": "Label for option",
        "additionalProperties": false
      }
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "$ref": "#/definitions/question"
  }
}

Если if/then/else не поддерживается вашим валидатором,альтернатива может быть:

{
  "definitions": {
    "question": {
      "type": "array",
      "title": "Question",
      "items": {
        "$ref": "#/definitions/template"
      }
    },
    "template": {
      "type": "object",
      "title": "Question template",
      "required": ["templateType","data"],
      "anyOf": [
        {
          "properties": {
            "templateType": { "type": "string", "pattern": "yesNo" },
            "data": { "$ref": "#/definitions/yesNo" }
          }
        },
        {
          "properties": {
            "templateType": { "type": "string", "pattern": "multiSelect" },
            "data": { "$ref": "#/definitions/multiSelect" }
          }
        }
      ]
    },
    "yesNo": {
      "type": "object",
      "title": "Yes/No question",
      "additionalProperties": false,
      "properties": {
        "label": {
          "type": "string"
        }
      }
    },
    "multiSelect": {
      "type": "array",
      "title": "Multi-select question",
      "items": {
        "type": "string",
        "title": "Label for option",
        "additionalProperties": false
      }
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "$ref": "#/definitions/question"
  }
}
...