JSON Схема (v04) anyOf с зависимостями - PullRequest
3 голосов
/ 28 мая 2020

У меня есть JSON, который может иметь либо номер счета IBAN, и в этом случае требуется BIC, либо account_number или оба.

Итак, это действительно (только account_number):

"bankaccount_data": [
    {
        "bic": null,
        "iban": null,
        "account_name": "Bankgiro",
        "account_number": "12345-6789",
        "bank_name": "Bankgiro",
        "type": "Bankgiro"
    }
]

И это действительно с iban и bic:

"bankaccount_data": [
    {
        "bic": "BANKBIC",
        "iban": "SE0123456789",
        "account_name": "Bankgiro",
        "account_number": null,
        "bank_name": "Bankgiro",
        "type": "Bankgiro"
    }
]

Даже это с обоими account_number и iban/bic :

"bankaccount_data": [
    {
        "bic": "BANKBIC",
        "iban": "SE0123456789",
        "account_name": "Bankgiro",
        "account_number": "12345-6789",
        "bank_name": "Bankgiro",
        "type": "Bankgiro"
    }
]

Моя проблема заключается в том, чтобы требовать ОБЕИХ iban и bic, если существует / или. У меня есть эта схема, которая этого не делает, но должна «иллюстрировать» мою потребность:

"bankaccount_data": {
  "type": "array",
  "items": [
    {
      "type": "object",
      "properties": {
        "account_name": { "type": "string" },
        "bank_name": { "type": [ "string", "null" ] },
        "type": { "type": "string" }
      },
      "required": [ "type" ],
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "bic":   { "type": "string" },
            "iban": { "type": "string" }
          },
          "required": [ "bic", "iban" ],
          "dependencies": {
              "iban": [
                  "bic"
              ],
              "bic": [
                "iban"
            ]
          }
        },
        {
          "type": "object",
          "properties": {
            "account_number":   { "type": "string" }
          },
          "required": [ "account_number" ]
        }
      ]
    }
  ]
}

1 Ответ

1 голос
/ 28 мая 2020

Я не совсем уверен, но я думаю, что вы спрашиваете, если присутствует iban или bic, тогда должен присутствовать и другой.

У вас были правильные идеи здесь . Однако это осложняется тем фактом, что ваши значения могут быть нулевыми, а не просто отсутствовать.

dependencies проверяет только наличие свойств, а не их значение. null по-прежнему является значением. dependencies не может помочь вам в вашей ситуации, поскольку вы всегда ожидаете, что ключи присутствуют в объекте.

Сначала давайте посмотрим на решение.

{
  "anyOf": [
    {
      "properties": {
        "bic":   { "type": "string" },
        "iban": { "type": "string" },
        "account_number": { "enum": [null]}
      },
      "required": [
        "iban",
        "bic"
      ]
    },
    {
      "required": [
        "account_number"
      ],
      "properties": {
        "bic":   { "enum": [null] },
        "iban": { "enum": [null] },
        "account_number": { "type": "string" }
      }
    }
  ]
}

https://jsonschema.dev/s/dg0CY

Причина, по которой вам нужно такое дублирование, заключается в том, что вам нужно полностью express условие, которое вы проверяете.

Значения массива anyOf являются подсхемами. Значения представляют собой полные схемы сами по себе.

Принятие ваших значений для anyOf, anyOf[0] делает express ограничение, которое вы ищете, однако anyOf[1] ничего не говорит о iban или bic, и поэтому "любая из" схем считается допустимой. Каждое значение в anyOf не знает о содержании другого; объединяются только результаты.

JSON Схема основана на ограничениях, поэтому разрешено все, что НЕ выражено.

В решении, которое я предоставил выше, каждая схема в anyOf проверяет полностью для требуемого условия.

Для вашего примера он работает в draft-07 так же, как draft-04, поэтому демонстрация такая же.

...