Вы были одним из правильных треков с 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
злоупотребляют, потому что с точки зрения естественного языка это звучит правильно.