我想知道我是否可以定义一个JSON模式(草案2019-09),该模式至少需要对象的许多可能属性中的一个,有时需要多个这些属性。我已经知道allOf、anyOf、oneOf和dependantrequried,但就是不知道如何以我想要的方式使用它们。
我有一个有四个键的对象:
amount
productId
invoiceId
jwt
我有以下要求:
amount
、productId
和invoiceId
不能同时位于对象中invoiceId
必须有jwt
jwt
可以单独使用,也可以与amount
或product
一起使用- 必须至少有一个四个关键的对象将尊重上述规则。
我已经尝试过这个模式,在大多数情况下,除了jwt
是单独的:
{
"type": "object",
"properties": {
"amount": {"type": "number"},
"productId": {"type": "string"},
"invoiceId": {"type": "string"},
"jwt": {"type": "string"},
},
"dependantRequried": {
"invoiceId": ["jwt"]
},
"oneOf": [
{"required": ["amount"]},
{"required": ["productId"]},
{"required": ["invoiceId"]},
]
}
将{"required": ["jwt"]}
添加到“oneOf”数组意味着当invoiceId
和jwt
在一起时它会失败。
预期结果:
| json| isValid|
| --------------|--------------|
| {"amount": 1}
|真|
| {"amount": 1, "jwt": "jwt-test"}
|真|
| {"productId": "prod-1"}
|真|
| {"productId": "prod-1", "jwt": "jwt-test"}
|真|
| {"invoiceId": "inv-1", "jwt": "jwt-test"}
|真|
| {"jwt": "jwt-test"}
|真|
| {"invoiceId": "inv-1"}
|假的|
| {"amount": 1, "productId": "prod-1"}
|假的|
| {"amount": 1, "productId": "prod-1", "jwt": "jwt-test"}
|假的|
1条答案
按热度按时间cclgggtu1#
你有几个选择。
1.
if
/then
/else
不要直接使用
required
,而是尝试使用if
/then
结构来禁止其他属性(如果存在)。第一个子模式表示,如果示例中存在
amount
,则其他两个不能有值,这是一种不允许使用它们的迂回方式。对其他两个属性重复此操作。最后一个涵盖了它们都不存在的情况。
2.使用
properties
即可这基本上做了同样的事情,但有些人可能认为它可读性较差。这是一个风格问题,真的。
这里第一个子模式只允许
amount
属性。同样,对其他两个属性重复此操作,并具有相同的最后一种情况。您还希望使用
anyOf
而不是oneOf
。oneOf
可以工作,但它是一个更密集的检查。一些实现可以在找到一个有效的子模式后,对其他子模式进行简化而不进行评估。但是,对于oneOf
,必须始终检查所有子模式。因为我们已经安排好了,所以只有一个是有效的,anyOf
就可以了。最后,你也有一个错字:
dependantRequried
->dependentRequired
。您可以在https://json-everything.net/json-schema上测试这些。