Условни оператори на 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 към allOf получавам „JSON не съответства на всички схеми от „allOf“. Невалидни индекси на схема: 1.' грешка при валидиране, това е преди дори да добавя else :(   -  person Gemma Morriss    schedule 20.11.2019


Отговори (1)


additionalProperties draft-07 ...

Валидирането с „additionalProperties“ се прилага само към дъщерните стойности на имена на екземпляри, които не съответстват на имена в „properties“ и не съответстват на нито един регулярен израз в „patternProperties“.

Това означава, че additionalProperties знае само ключови думи, които се появяват в properties или които съответстват на регулярния израз от patternProperties. Използването на additionalProperties с required без properties ще създаде неуспешна схема (нищо няма да премине проверка).

Вместо това можете да разделите притесненията на това, което всъщност искате...

  • Искате тип, ключ и стойност всички да бъдат низове. Един от...
  • Ако типът е AnyValue, тогава изисквайте само тип и ключ.
  • Ако типът е ExactValue, тогава изисквайте тип, ключ и стойност.

Това също е по-лесно за разбиране. Here's a демонстрация на живо с вашите данни.

{
  "$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