我有一个遗留API我试图在JSON Schema中定义,并且该对象有一个奇怪的结构,其中有一组4个属性,其中任何一个都是必需的,其中3个是互斥的。之后是超过30个共享的可选属性,我会将它们记录为...
。
如,
{ "foo": "bar", "baz": 1234, ... } // OK
{ "foo": "bar", "buzz": 1234, ... } // OK
{ "foo": "bar", "fizz": 1234, ... } // OK
{ "foo": 1234, ... } // OK
{ "baz": 1234, ... } // OK
{ ... } // NOT OK
{ "baz": 1234, "buzz": 1234, ... } // NOT OK
我可以执行oneOf
但不允许foo
与其他人一起出现,anyOf
允许baz
,buzz
和fizz
相互存在,这是不可能的。
我尝试定义如下内容:
{
"type": "object",
"properties": {
"foo": {"type": "string"},
"baz": {"type": "number"},
"buzz": {"type": "number"},
"fizz": {"type": "number"}
},
"anyOf": [
{"required": ["foo"]},
{"required": [{"oneOf": [
{"required": ["baz"]},
{"required": ["buzz"]},
{"required": ["fizz"]}
]}
]}
]
}
和
{
"type": "object",
"properties": {
"foo": {"type": "string"},
"baz": {"type": "number"},
"buzz": {"type": "number"},
"fizz": {"type": "number"}
},
"anyOf": [
{"required": ["foo"]},
{"oneOf": [
{"required": ["baz"]},
{"required": ["buzz"]},
{"required": ["fizz"]}
]
}
]
}
但这不起作用,我只是不了解json架构还知道这是否可行。
答案 0 :(得分:16)
有趣!可能有一个更简洁的解决方案,但我们在这里......
“互斥”约束可以通过禁止属性的成对组合来表达:
{
"not": {
"anyOf": [
{"required": ["baz", "buzz"]},
{"required": ["buzz", "fizz"]},
{"required": ["fizz", "baz"]}
]
}
}
“至少一个”约束可以用anyOf
表示:
{
"anyOf": [
{"required": ["foo"]},
{"required": ["baz"]},
{"required": ["buzz"]},
{"required": ["fizz"]}
}
}
如果您只是将这两个约束组合到一个模式中,那么它应该可以工作:
{
"not": {"anyOf": [...]},
"anyOf": ...
}
答案 1 :(得分:6)
您可以使用成对排除在JSON模式中使属性互斥,但这会导致组合爆炸。当你有许多互斥的属性时,这就成了一个问题。
线性解决方案的形式如下:
如果你有很多属性,这只会得到回报。
{ "oneOf": [
{ "required": ["baz"] },
{ "required": ["buzz"] },
{ "required": ["fizz"] },
{ "not":
{ "anyOf": [
{ "required": ["baz"] },
{ "required": ["buzz"] },
{ "required": ["fizz"] }
] }
}
] }
将此与@ cloudfeet的答案相结合,以获得您特定问题的答案。