Существует несколько способов достижения требуемого эффекта даже без использования JSON Schema draft-07 if-then-else .
логический оператор и импликация (draft-04 и выше)
Логическое значение здесь: если присутствует «средний», то требуется «громоздкий» может быть переведен в «отсутствует» ИЛИ «громоздкий» «требуется» (последнее подразумевает «средний» присутствует ), который можно доработать до «средний» не требуется ИЛИ «громоздкий» «требуется» (поскольку, если присутствует «средний», онбудет удовлетворять условию необходимости).См. Схему ниже:
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"not" : { "required" : ["medium"] }
},
{
"required" : ["bulky"]
}
],
"additionalProperties" : false
Проверьте здесь для справки:
Схема JSON - действительна, если объект * не * содержит определенное свойство
http://json -schema.org / latest / json-schema-validation.html # rfc.section.6.7
"anyOf" - логическое ИЛИ, "oneOf" - XOR, "allOf«- AND,« not »- отрицание, но обратите внимание на спецификацию:
Экземпляр действителен для этого ключевого слова, если он не может успешно выполнить проверку по схеме, определенной этим ключевым словом.
draft-06 - зависимости + propertyNames
Наиболее очевидно.Я не уверен, что вы исключили этот вопрос в своем вопросе, так что оставьте здесь на всякий случай.Обратите внимание, что вместо «AdditionalProperties», если вы не хотите просто ограничивать допустимые ключи, можно использовать «propertyNames» (и фактически это то, для чего оно было добавлено).
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"dependencies" : {
"medium" : ["bulky"]
},
"propertyNames" : {
"enum" : [
"smaller",
"larger",
"medium",
"bulky"
]
}
Проверьте здесь дляссылка: http://json -schema.org / latest / json-schema-validation.html # rfc.section.6.5.7
Обновление
После уточнения в комментарии:
для draft-6 - здесь «не требуется» означает, что если «среднего» не существует, то громоздкий «не должен присутствовать»
«не должен» означаетпредотвращение громоздкого присутствия.
Я перефразирую ваше состояние:
1.если «средний» существует, «громоздкий» должен присутствовать -> оба ключа должны присутствовать одновременно
2.если «среднего» не существует, «громоздкий» не должен присутствовать также -> обе клавиши не должны присутствовать одновременно
Может«громоздкий» существует, а «средний» не существует?
Нет.См. 2. И наоборот (см. 1.).Булево равенство (дополняющее логическое XOR).
Таким образом, если «громоздкий» существует - это значит, что «средний» должен быть всегда ... Это означает, что оба обязательны или оба не должно быть обязательным (или даже разрешенным) .
Поскольку это draft-06, вы также можете использовать "propertyNames" для определения разрешенных имен свойств (вид ярлыка для этой логики).
логический оператор и импликация (draft-06 и выше)
Правильная логическая операция, преобразованная в схему JSOn, будет выглядеть следующим образом:
"oneOf" : [
{ "required" : ["medium","bulky"] }, <== this schema is satisfied if both keys appear in validated instance
{
"allOf" : [ <== !medium ^ !bulky - due to how "not" works in schema context
{"not" : { "required" : ["medium"] } },
{"not" : { "required" : ["bulky"] } },
]
}
]
XOR - ИЛИ (оба требуются) ИЛИ (средний не требуется И громоздкий не требуется).
Обратите внимание, что я не делаю "not": {"required": ["medium", "громоздкий"]} как при наличии только одного из этих ключей "требуемая «схема потерпит неудачу, что будет означать, что« нет »вернет успешный результат проверки.Нужно перефразировать его, используя законы де Моргана:
"oneOf" : [
{ "required" : ["medium","bulky"] },
{
"not" : { <=== !medium ^ !bulky = !(medium v bulky)
"anyOf" : [
{ "required" : ["medium"] },
{ "required" : ["bulky"] },
]
}
}
]
Однако использование «propertyNames» также поможет.См. Следующую схему:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"properties": {
"smaller": {"type": "number"},
"larger": { "type": "number" },
"medium":{"type":"string"},
"bulky":{"type":"string"}
},
"required":["smaller","larger"],
"anyOf" : [
{
"required" : ["medium","bulky"]
},
{
"propertyNames" : {
"enum" : [
"smaller",
"larger"
]
},
}
],
"examples" : [
{
"smaller" : 1,
"larger" : 2,
},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",
"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,
"medium" : ""
},
{
"smaller" : 1,
"larger" : 2,
"bulky" : "test",
},
]
}
Это отвечает на ваш вопрос?