2016-12-14 1 views
1

У меня есть json-схема, которая работает, когда я использую 2 oneOf для 2 вариантов между обязательными полями. Но я не знаю, как сделать то же самое с дополнительными полями.2 oneOf in json schema: 1 required 1 optional

Моя схема:

{ 
    "$schema": "http://json-schema.org/draft-04/schema#", 
    "properties": { 
    "a": { 
     "type": "number" 
    }, 
    "b": { 
     "type": "number" 
    }, 
    "c": { 
     "type": "number" 
    }, 
    "d": { 
     "type": "number" 
    }, 
    "e": { 
     "type": "number" 
    } 
    }, 
    "required": ["a"], 
    "oneOf": [ 
    {"required": ["b"]}, 
    {"required": ["c"]} 
    ], 
    "oneOf": [ 
    {"required": ["d"]}, 
    {"required": ["e"]} 
    ] 
} 

Как я могу преобразовать, чтобы сделать d и е опциональным (в то время как никогда не имея оба сразу)?

ответ

1

Вот gist with my solution, показанный на http://jsonschemalint.com. (Очень удобный инструмент!)

Свойства d и e уже определены и разрешены (но не обязательно) в любой комбинации. Для того, чтобы эти два свойства взаимно исключают друг друга, мы говорим, что экземпляр должен not соответствовать схеме, которая имеет оба свойства:

{ 
    "$schema": "http://json-schema.org/draft-04/schema#", 
    "properties": { 
    "a": {"type": "number"}, 
    "b": {"type": "number"}, 
    "c": {"type": "number"}, 
    "d": {"type": "number"}, 
    "e": {"type": "number"} 
    }, 
    "required": ["a"], 
    "oneOf": [ 
     {"required": ["b"]}, 
     {"required": ["c"]} 
    ], 
    "not" : {"required" : ["d","e"]} 
} 

Это хорошо работает, но он начинает получать грязный, если у вас есть более чем два свойства в вашем взаимоисключающими группа. Например, если мы хотим добавить свойство f и сделать его взаимоисключающими по отношению к d и e, мы должны были бы запретить три различных комбинации:

"not" : { 
    "anyOf"{ 
     {"required" : ["d","e"]}, 
     {"required" : ["d","f"]}, 
     {"required" : ["e","f"]}, 
    } 
    } 

Вот альтернатива, более многословным, но масштабируется до более крупные комплексы взаимоисключающих свойств:

"oneOf" : [ 
    {"required" : ["d"]}, 
    {"required" : ["e"]}, 
    {"required" : ["f"]}, 
    { 
     "not" : { 
     "anyOf" : [ 
      {"required" : ["d"]}, 
      {"required" : ["e"]}, 
      {"required" : ["f"]} 
     ] 
     } 
    } 
    ] 

Каждое свойство, добавленное к группе, требует ровно две строки.

Поскольку наша схема теперь имеет два oneOf ограничения, мы должны объединить их с помощью allOf:

{ 
    "$schema": "http://json-schema.org/draft-04/schema#", 
    "properties": { 
    "a": {"type": "number"}, 
    "b": {"type": "number"}, 
    "c": {"type": "number"}, 
    "d": {"type": "number"}, 
    "e": {"type": "number"}, 
    "f": {"type": "number"} 
    }, 
    "required": ["a"], 
    "allOf": [ 
    { 
     "oneOf": [ 
      {"required": ["b"]}, 
      {"required": ["c"]} 
     ] 
    }, 
    { 
     "oneOf" : [ 
     {"required" : ["d"]}, 
     {"required" : ["e"]}, 
     {"required" : ["f"]}, 
     { 
      "not" : { 
      "anyOf" : [ 
       {"required" : ["d"]}, 
       {"required" : ["e"]}, 
       {"required" : ["f"]} 
      ] 
      } 
     } 
     ] 
    } 
    ] 
} 
+0

Спасибо за вашу помощь. С вашим решением, '{" a ": 1," b ": 1}' или '{" a ": 1," c ": 1}' недействительны, но мне они нужны. Как я могу адаптироваться к моему делу? – lovelace63

+1

Просто обновил свой пример и объяснение, чтобы показать решение. Хороший улов! –

+1

lovelace63, после того как вы приняли мой ответ, я нашел \t гораздо более чистое решение. Это не требует повторения списка дополнительных свойств, поэтому его проще поддерживать. Это также позволяет упростить создание нескольких независимых наборов взаимоисключающих свойств, необходимых или необязательных. Пожалуйста, взгляните и дайте мне знать, если у вас возникнут проблемы с этим. –

Смежные вопросы