JSON Схема одна без обязательной - PullRequest
0 голосов
/ 26 февраля 2020

В JSON Schema черновике 7 или 8, как правильно сказать, что мы хотим, по желанию, один из атрибутов, но не оба. Я могу создать с ключевым словом required, но тогда вы должны включить один из обязательных атрибутов. Это то, о чем я могу подумать, это правильно?

В этом примере я пытаюсь подтвердить, что требуется field_1, и нам нужен либо один из field_2, field_3, либо ни один из них. (см. примеры)

{
  "$schema": "http://json-schema.org/draft-08/schema#",
  "type": "object",
  "properties": {
    "field_1": {
      "type": "string"
    },
    "field_2": {
      "type": "string"
    },
    "field_3": {
      "type": "string"
    }
  },
  "required": [
    "field_1"
  ],
  "oneof": [
    {
      "properties": [
        "field_2"
      ]
    },
    {
      "properties": [
        "field_3"
      ]
    }
  ],
  "additionalProperties": false,
  "examples": [
    {
      "field_1": "1",
      "field_2": "2"
    },
    {
      "field_1": "1",
      "field_3": "3"
    },
    {
      "field_1": "1"
    }
  ]
}

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Вот еще несколько вариантов, которые можно добавить к ответу @ gregdennis.

Зависимости

Это отличный пример использования ключевого слова dependencies. Это говорит: «если есть« field_2 », то не может быть« field_3 », и« если есть «field_3», то не может быть «field_2». Если ни «field_2», ни «field_3» не существует, никакие ограничения не применяются, и схема проходит. один лайнер. Если "field_1" требуется и допускается только одно из "field_2" или "field_2", в этом объекте может быть не более двух свойств. Осторожно, это решение может быть умнее, чем оно того стоит. Поскольку это ограничение работает косвенно, в будущем это может привести к трудностям обслуживания.

"maxProperties": 2

if / then

Это просто более подробная версия параметров dependencies, но может быть более информативным для тех, кто читает схему.

"allOf": [
  {
    "if": { "required": ["field_2"] },
    "then": { "not": { "required": ["field_3"] } }
  },
  {
    "if": { "required": ["field_3"] },
    "then": { "not": { "required": ["field_2"] } }
  }
]
1 голос
/ 26 февраля 2020

[РЕДАКТИРОВАНИЕ - СМОТРИ ТРЕТЬЕ РЕШЕНИЕ НИЖЕ]

Решение 1 - Хотя бы один, но не оба (подробный)

Я бы добавил allOf с a nested oneOf:

{
  ...
  "allOf": [
    {
      "oneOf": [
        {"required": ["field_2"]},
        {"required": ["field_3"]}
      ],
    },
    {
      "not": {
        "required": ["field_2", "field_3"]
      }
    }
  ],
  ...
}

Для этого требуется наличие одного из двух полей, но не обоих.


Решение 2 - Как минимум одно, но не оба

Я думаю, что это можно еще больше упростить, используя только oneOf:

{
  ...
  "oneOf": [
    {"required": ["field_2"]},
    {"required": ["field_3"]}
  ],
  ...
}
  • Если ни того, ни другого нет, то оба они потерпят неудачу, а oneOf не удастся.
  • Если кто-то есть, то проходит oneOf.
  • Если оба присутствуют, оба они пройдут, и oneOf завершится неудачей.

Да, так лучше. Глядя на то, что у вас было, я думаю, что это то, что вы пытались сделать, поэтому вы были действительно близко!


Решение 3 - Максимум один

Чтобы пройти, когда нет ни одного поля, вам нужно первое решение, но замените allOf на anyOf:

{
  ...
  "anyOf": [
    {
      "oneOf": [
        {"required": ["field_2"]},
        {"required": ["field_3"]}
      ],
    },
    {
      "not": {
        "required": ["field_2", "field_3"]
      }
    }
  ],
  ...
}
  • Если ни того, ни другого нет, тогда подсхема not пройдет и anyOf проходит.
  • Если кто-то есть, то подсхема oneOf пройдет, и пройдет anyOf.
  • Если оба присутствуют, то
    • обе подсхемы oneOf пройдут, поэтому oneOf завершится неудачей
    • not подсхема завершится неудачей
    • , поэтому anyOf завершится неудачей

Вы можете протестировать эти решения здесь

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