проверить 2 возможных типа данных в jsonchema - PullRequest
0 голосов
/ 07 ноября 2018

Я потратил весь день, пытаясь заставить это работать, выложу список ссылок и вещей, которые я попробовал после вопроса.

Итак, вот моя jsonschema:

{
    "data": [{
        "required": "effort",
        "decisive": "maybe",
        "field1": 7
    },
    {
        "required": "effort",
        "decisive": "no",
        "field1": 6
    }],
    "schema": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
                "field1": {
                    "type": "string",
                    "pattern": "[A-Z]",
                    "title": "field1"
                },
                "required": {
                    "type": "string",
                    "title": "required",
                    "readonly": true
                },
                "decisive": {
                    "type": "string",
                    "title": "Decisive",
                    "enum": ["yes", "no", "maybe", "not now"]
                }

            }
        }
    }
}

Рассмотрим точную часть jsonschema, но с элементом field1 следующим образом:

"field1": {
    "type": "integer",
    "minimum": 5,
    "maximum": 10,
    "title": "field1"
}
  • Первый пример проверяет только заглавные буквы в своем поле1
  • Второму требуется целое число от 5 до 10.

Как сделать так, чтобы они подтвердили любой из них, так что оба они приняты -

  • либо только заглавные буквы
  • или целое число от 5 до 10?

Да - поле1 в разделе данных выше не так важно, это желаемое значение по умолчанию.

Я испробовал все виды идей - с одним из - здесь , здесь , здесь

param - здесь

дополнительные свойства - здесь

требуется - здесь

Интуитивно понятным было использование шаблона oneOf on, но oneOf, как упоминалось во многих вопросах, ничего не делает внутри раздела свойств, а только за его пределами. Поэтому я попытался иметь точно такие же свойства внутри oneOf только с одним отличием, как описано выше. Это тоже не сработало и содержит много повторений, которых нужно как-то избежать.

Кто-нибудь знает, как это решить? У меня нет идей ..

1 Ответ

0 голосов
/ 08 ноября 2018

Вы были одним из правильных треков с oneOf, за исключением того, что вы на самом деле хотите - anyOf. Почти каждый раз, когда вы думаете, что хотите oneOf, вы действительно хотите anyOf. Помните, что значения properties являются схемами, как и любые другие. Вы можете использовать логические ключевые слова там, как и везде.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "field1": {
                "title": "field1"
                "anyOf": [
                    {
                        "type": "string",
                        "pattern": "[A-Z]"
                    },
                    {
                        "type": "integer",
                        "minimum": 5,
                        "maximum": 10
                    }
                ]
            },
            "required": {
                "type": "string",
                "title": "required",
                "readonly": true
            },
            "decisive": {
                "type": "string",
                "title": "Decisive",
                "enum": ["yes", "no", "maybe", "not now"]
            }

        }
    }
}

Редактировать 1

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

{
  "type": "object",
  "properties": {
    "anyOf": [
      {
        "field1": { ... }
      },
      {
        "field1": { ... }
      }
    ],
    "required": { ... },
    "decisive": { ... }
  }
}

Редактировать 2

Поскольку это появилось в комментариях, вот лучшее объяснение того, почему oneOf почти никогда не является правильным выбором. Чтобы было ясно, oneOf всегда будет работать вместо anyOf. Если бы anyOf не существовало, JSON Schema не потеряла бы выразительную силу.

Однако, anyOf - более точный инструмент. Использование oneOf, когда anyOf будет делать, похоже на использование кувалды для забивания гвоздя, когда в вашем наборе инструментов есть простой молоток с раздвоенным хвостом.

anyOf - логическая операция ИЛИ. oneOf - логическая операция «исключающее ИЛИ» (XOR). «XOR» настолько мало полезен, что современные языки даже не поддерживают его. ИЛИ обычно обозначается оператором ||. XOR не имеет аналогов.

anyOf означает любой пунктов может быть правдой. oneOf означает один и только один элементов может быть истинным. Когда вы используете oneOf, средство проверки должно протестировать все схем, чтобы убедиться, что одна схема проверяется как истинная, а остальные - как ложная. Когда вы используете anyOf, валидатор может остановиться, как только обнаружит схему, которая проверяется как истинная. Это называется «короткое замыкание», и все современные языки программирования делают это при оценке операций ИЛИ. Когда схемы являются взаимоисключающими (которые они почти всегда являются), продолжение проверки схем после их обнаружения является пустой тратой, и поэтому их следует избегать.

Я думаю, что oneOf злоупотребляют, потому что с точки зрения естественного языка это звучит правильно.

...