[英]JSON Schema oneof without required
In JSON Schema
draft 7 or 8 what is the right way to say that we want optionally either one of the attributes but not both.在JSON Schema
草案 7 或 8 中,正确的说法是我们想要可选的属性之一而不是两者。 I can construct with required
keyword, but then you have to include either one of the required attributes.我可以用required
关键字构造,但是你必须包含其中一个必需的属性。 This is what I can think of, is this correct?这是我能想到的,这是正确的吗?
In this example I'm trying to validate field_1
is required and we want either one of field_2
, field_3
or none of them.在这个例子中,我试图验证field_1
是必需的,我们想要field_2
、 field_3
之一,或者都不想要。 (see examples) (见例子)
{
"$schema": "http://json-schema.org/draft-08/schema#",
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": "string"
},
"field_3": {
"type": "string"
}
},
"required": [
"field_1"
],
"oneof": [
{
"properties": [
"field_2"
]
},
{
"properties": [
"field_3"
]
}
],
"additionalProperties": false,
"examples": [
{
"field_1": "1",
"field_2": "2"
},
{
"field_1": "1",
"field_3": "3"
},
{
"field_1": "1"
}
]
}
I would add an allOf
with a nested oneOf
:我会添加一个带有嵌套allOf
的oneOf
:
{
...
"allOf": [
{
"oneOf": [
{"required": ["field_2"]},
{"required": ["field_3"]}
],
},
{
"not": {
"required": ["field_2", "field_3"]
}
}
],
...
}
This requires that one of the two fields are present, but not both.这要求两个字段之一存在,但不能同时存在。
I think this can be further simplified by using just the oneOf
:我认为这可以通过仅使用oneOf
进一步简化:
{
...
"oneOf": [
{"required": ["field_2"]},
{"required": ["field_3"]}
],
...
}
oneOf
fails.如果两者都不存在,那么这些都将失败,并且oneOf
失败。oneOf
passes.如果有一个,那么oneOf
会通过。oneOf
fails.如果两者都存在,那么这两个都会通过,而oneOf
失败。Yeah, this is better.是的,这更好。 Looking at what you had, I think this is what you were trying to do, so you were really close!看看你所拥有的,我认为这就是你想要做的,所以你真的很接近!
To pass when neither field are present you need the first solution, but change the allOf
to an anyOf
:要在两个字段都不存在时通过,您需要第一个解决方案,但将allOf
更改为anyOf
:
{
...
"anyOf": [
{
"oneOf": [
{"required": ["field_2"]},
{"required": ["field_3"]}
],
},
{
"not": {
"required": ["field_2", "field_3"]
}
}
],
...
}
not
subschema will pass, and the anyOf
passes.如果两者都不存在,则not
子模式将通过,并且anyOf
将通过。oneOf
subschema will pass, and the anyOf
passes.如果有一个,那么oneOf
子模式将通过,而anyOf
将通过。oneOf
subschemas will pass, so the oneOf
fails oneOf
子模式都将通过,因此oneOf
失败not
subschema will fail非子模式将not
anyOf
fails所以anyOf
失败了Here's a couple more options to add to @gregdennis's answer.这里有几个选项可以添加到@gregdennis 的答案中。
This is a great use case for the dependencies
keyword.这是dependencies
关键字的一个很好的用例。 This says, "if there is a "field_2" there can't be a "field_3" and, "if there is a "field_3" there can't be a "field_2".这就是说,“如果有一个“field_2”,就不可能有一个“field_3”,并且,“如果有一个“field_3”,就不可能有一个“field_2”。 If neither "field_2" or "field_3" exist, no constraints apply and the schema passes.如果“field_2”或“field_3”都不存在,则不应用任何约束并且架构通过。
"dependencies": {
"field_2": { "not": { "required": ["field_3"] } },
"field_3": { "not": { "required": ["field_2"] } }
}
This one is a bit hacky, but it has the benefit of being a one liner.这个有点老套,但它的好处是成为一个班轮。 If "field_1" is required and only one of "field_2" or "field_2" are allowed, there can not be more than two properties present in this object.如果需要“field_1”并且只允许“field_2”或“field_2”其中之一,则此对象中的属性不能超过两个。 Beware, this solution might be more clever than it's worth.当心,这个解决方案可能比它的价值更聪明。 Because this constraint works indirectly, it can be lead to maintenance difficulties in the future.由于此约束间接起作用,因此可能会导致将来的维护困难。
"maxProperties": 2
This is just a more verbose version of the dependencies
options, but might be more descriptive for someone reading the schema.这只是dependencies
项选项的更详细版本,但对于阅读架构的人来说可能更具描述性。
"allOf": [
{
"if": { "required": ["field_2"] },
"then": { "not": { "required": ["field_3"] } }
},
{
"if": { "required": ["field_3"] },
"then": { "not": { "required": ["field_2"] } }
}
]
I had to try to figure this out for 3 fields where field 1 is also optional.我不得不尝试为 3 个字段解决这个问题,其中字段 1 也是可选的。 Doing so revealed @gregdennis's answer to Solution 3 was slightly more than it needed to be, this accomplishes the same goal as there is no need to check for required single values as neither are required.这样做揭示了@gregdennis 对解决方案 3的回答比它需要的略多,这实现了相同的目标,因为不需要检查所需的单个值,因为两者都不需要。
{
...
"not": {
"required": ["field_2", "field_3"]
}
...
}
To do this for 3, it looks like:要为 3 执行此操作,它看起来像:
{
...
"not": {
"anyOf": [{
"required": ["field_1", "field_2", "field_3"]
},
{
"required": ["field_1", "field_2"]
},
{
"required": ["field_2", "field_3"]
},
{
"required": ["field_1", "field_3"]
}]
}
...
}
As you add more fields, this obviously becomes less useful.随着您添加更多字段,这显然变得不那么有用。 So a better solution with room to go to N is the following:因此,有空间去 N 的更好解决方案如下:
{
...
"anyOf": [
{
"oneOf": [
{"required": ["field_1"]},
{"required": ["field_2"]},
{"required": ["field_3"]}
]
},
{
"not": {
"anyOf": [
{"required": ["field_1"]},
{"required": ["field_2"]},
{"required": ["field_3"]}
]
}
}
]
...
}
You can do this as follows:您可以按如下方式执行此操作:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"field_1": {
"type": "string"
}
},
"oneOf": [
{
"properties": {
},
"additionalProperties": false
},
{
"properties": {
"field_2": {
"type": "string"
}
},
"required": ["field_2"],
"additionalProperties": false
},
{
"properties": {
"field_3": {
"type": "string"
}
},
"required": ["field_3"],
"additionalProperties": false
}
],
"required": [
"field_1"
]
}
As stated in this book : "oneOf: (XOR) Must be valid against exactly one of the subschemas".如本书所述:“oneOf: (XOR) 必须对其中一个子模式有效”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.