Как переключить регистр полей в схеме JSON?

Я использую питон jsonschema проверить записи JSON. Вот пример схемы. Здесь есть только два случая, но представьте себе похожий сценарий, в котором вместо этого выложены сотни случаев.

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "oneOf": [
      {
        "type": "object",
        "required": ["a", "b", "c"],
        "properties": {
          "a": {"type": "integer", "enum": [0]},
          "b": {"type": "integer", "enum": [0, 2, 4, 6, 8]},
          "c": {"type": "string", "enum": ["always the same"]}
        }
      },
      {
        "type": "object",
        "required": ["a", "b", "c"],
        "properties": {
          "a": {"type": "integer", "enum": [1]},
          "b": {"type": "integer", "enum": [1, 3, 5, 7, 9]},
          "c": {"type": "string", "enum": ["always the same"]}
        }
      }
    ]
}

Ключевым вопросом является дублирование "c" поле. Я хотел бы иметь возможность включить дело "a", подтверждающий для соответствующего "b" но имея "c" всегда оставайся таким же. Я не хочу объяснять "c" сто разных времен. Возможно ли это сделать?

Спасибо!

2 ответа

Решение

Да, это может быть сделано. На самом деле, это хорошая практика, чтобы положить только в anyOf/oneOf части, которые меняются.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "c": { "const": "always the same" }
  },
  "required": ["a", "b", "c"],
  "anyOf": [
    {
      "properties": {
        "a": { "const": 0 },
        "b": { "enum": [0, 2, 4, 6, 8] }
      }
    },
    {
      "properties": {
        "a": { "const": 1 },
        "b": { "enum": [1, 3, 5, 7, 9] }
      }
    }
  ]
}

Аswitchоператор не существует в схеме JSON. Здесь было долгое обсуждение предложения по этому поводу . Без него есть несколько возможных способов обеспечить эту функциональность:

любой из / один из

Решение, предложенное Джейсоном Дерозье, подойдет, но с некоторыми оговорками:

  1. У вас может быть случай «по умолчанию», только если вы создадите его вручную с другими возможными значениями. Например, в ответе Джейсона это может выглядеть примерно так:
            "properties": {
        "a": { "not": { "enum": [0, 1] } },
        "b": { "enum": [10, 11, 12] }
      }
  1. При использовании необходимо следить за тем, чтобы все случаи были взаимоисключающими и не могли перекрываться.

если... то

Лично я предпочитаю наборif...thenфрагменты (в окруженииallOf) вместо. Это имеет те же предостережения, что и выше. Одним из преимуществ является то, что становится ясно, какое свойство «включается». Другое дело, если вы используете валидатор, такой как ajv , сообщения проверки, полученные, когда JSON не проходит проверку, будут лучше определять проблему. ЕслиanyOfилиoneOfиспользуется, вы просто получите подтверждающее сообщение о том, что все это не было выполнено, что делает причину менее ясной. Но используяifфрагменты, вам говорят, какой из них не был встречен и почему. Вот пример Джейсона, преобразованный в этот синтаксис:

      {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "c": { "const": "always the same" }
  },
  "required": ["a", "b", "c"],
  "allOf": [
    {
      "if": {
        "properties": {
          "a": { "const": 0 },
        }
      },
      "then": {
        "properties": {
          "b": { "enum": [0, 2, 4, 6, 8] }
        }
      }
    },
    {
      "if": {
        "properties": {
          "a": { "const": 1 },
        }
      },
      "then": {
        "properties": {
          "b": { "enum": [1, 3, 5, 7, 9] }
        }
      }
    }
  ]
}
Другие вопросы по тегам