Условные выражения схемы JSON

Я пытаюсь проверить то, что я считал простой схемой JSON в качестве файла конфигурации для моего приложения Python, это список пар ключ / значение заголовка, единственная сложность заключается в том, что если в поле «Тип» установлено значение «AnyValue», тогда ключ значения не требуется.

Вот схема как она есть:

{
    "definitions":
    {
        'KeyEntry':
        {
             "properties":
             {
                'Type': {"type" : "string"},
                'Key': {"type": "string"}
             },
             "required": ['Type', 'Key'],
            "anyOf":
            [
                {
                    "if":
                    {
                        "properties": {'Type': {"const": 'ExactValue'}}
                    },
                    "then":
                    {
                        "properties":
                        {
                            'Value': {"type": "string"}
                        },
                        "required": ['Type', 'Key', 'Value'],
                        "additionalProperties": false
                    }
                },
                {
                    "if":
                    {
                        "properties": {'Type': {"const": 'AnyValue'}}
                    },
                    "then":
                    {
                        "required": ['Type', 'Key'],
                        "additionalProperties": false
                    }
                }
            ]
        }
    },

    "type": "object",
    "properties":
    {
        'Keys':
        {
            "type": "array",
            "items": {"$ref": "#/definitions/KeyEntry"}
        }
    },
    "required": ['Keys']
}

Большая часть проверки работает, за исключением случаев, когда я добавляю дополнительные значения, хотя я установил "additionalProperties": false по всей схеме.

Вот пример, в котором допустимы дополнительные значения:

{
    "Keys": [

        {
            "Type": "AnyValue",
            "Key": "Version",
            "Y": "Yes",
            "N": "No",
        }
    ]
}

Пожалуйста, кто-нибудь может помочь объяснить, где я ошибся и как мне это исправить?


person Gemma Morriss    schedule 19.11.2019    source источник
comment
Ах, это классический камень преткновения. Я не могу полностью проверить решение прямо сейчас, но что произойдет, если вы измените значение anyOf на allOf и добавите else: false в блоки if?   -  person Relequestual    schedule 20.11.2019
comment
Даже если это не поможет, я помогу, как только смогу. знак равно   -  person Relequestual    schedule 20.11.2019
comment
@Relequestual Привет, как только может anyOf to allOf, я получаю «JSON не соответствует всем схемам из allOf». Неверные индексы схемы: 1. ' ошибка проверки, это еще до того, как я добавлю еще :(   -  person Gemma Morriss    schedule 20.11.2019


Ответы (1)


additionalProperties draft-07 ...

Проверка с помощью «additionalProperties» применяется только к дочерним значениям имен экземпляров, которые не соответствуют никаким именам в «properties» и не соответствуют никаким регулярным выражениям в «patternProperties».

Это означает, что additionalProperties осведомлены только о ключевых словах, которые появляются в properties или соответствуют регулярному выражению из patternProperties. Использование additionalProperties с required без properties приведет к созданию схемы неисправности (ничто не пройдет проверку).

Вместо этого вы можете разделить проблемы на то, что вам действительно нужно ...

  • Вы хотите, чтобы тип, ключ и значение были строками. Один из...
  • Если тип AnyValue, то требуются только тип и ключ.
  • Если тип - ExactValue, требуются тип, ключ и значение.

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

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "KeyEntry": {
      "properties": {
        "Type": {
          "type": "string"
        },
        "Key": {
          "type": "string"
        },
        "Value": {
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": [
        "Type",
        "Key"
      ],
      "anyOf": [
        {
          "if": {
            "properties": {
              "Type": {
                "const": "ExactValue"
              }
            }
          },
          "then": {
            "required": [
              "Type",
              "Key",
              "Value"
            ]
          },
          "else": false
        },
        {
          "if": {
            "properties": {
              "Type": {
                "const": "AnyValue"
              }
            }
          },
          "then": {
            "required": [
              "Type",
              "Key"
            ]
          },
          "else": false
        }
      ]
    }
  },
  "type": "object",
  "properties": {
    "Keys": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/KeyEntry"
      }
    }
  },
  "required": [
    "Keys"
  ]
}
person Relequestual    schedule 20.11.2019