数组中特定对象属性的JSON模式条件检查
我想通过AJV-JSON模式验证或自定义关键字(最好是这样):数组可以有1或2个JSON对象,类型为“admin”和“guest”。“type”:“guest”对象将始终存在,“type”:“admin”对象是可选的 附加说明: -将来,对象本身可能包含附加属性和嵌套对象 -其他有效的枚举是superadmin、admin、user和guest -数组中的类型序列是:superadmin、admin、user和guest。可以检查顺序吗?(尽管是可选的) -“来宾”类型的对象将始终存在,并且将存在唯一类型的对象。如果任何对象类型(如superadmin、admin、user和guest)再次出现,则为错误 //以下是模式:数组中特定对象属性的JSON模式条件检查,json,jsonschema,json-schema-validator,ajv,Json,Jsonschema,Json Schema Validator,Ajv,我想通过AJV-JSON模式验证或自定义关键字(最好是这样):数组可以有1或2个JSON对象,类型为“admin”和“guest”。“type”:“guest”对象将始终存在,“type”:“admin”对象是可选的 附加说明: -将来,对象本身可能包含附加属性和嵌套对象 -其他有效的枚举是superadmin、admin、user和guest -数组中的类型序列是:superadmin、admin、user和guest。可以检查顺序吗?(尽管是可选的) -“来宾”类型的对象将始终存在,并且将存
{
"type": "object",
"properties": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "enum": ["guest", "admin"]
},
"rights": {"type": "string"},
"hyperLink": {"type": "string", "format": "uri"}
}
}
}
}
我需要在json中的某个地方添加“checkTypeAndValue”标志,这样我就可以获取完整的json对象和相应的属性来进行编程检查
const checkTypeAndValue = function (schema, completeJSONObj) {
//
};
ajv.addKeyword('checkTypeAndValue', {
validate: checkTypeAndValue,
errors: true
});
下面是一些有效和无效的例子:
/Valid 1: As type is 'admin' and so 'rights' SHOULD NOT be in 'guest' object
{
[
{
"type":"admin",
"hyperLink": "http://www.someguest.com",
"rights":"all"
},
{
"type":"guest",
"hyperLink": "http://www.someadmin.com"
}
]
}
//Valid 2: You can have a SINGLE 'guest' object. 'admin' object is not required all the time
{
[
{
"type":"guest",
"hyperLink": "http://www.someadmin.com",
"rights": "limited" //MANDATORY or REQUIRED Attribute
}
]
}
//InValid
{
[
{
"type":"admin",
"hyperLink": "http://www.someguest.com",
"rights":"all"
},
{
"type":"guest",
"hyperLink": "http://www.someadmin.com",
"rights":"limited"
//Error ==> As rights=all is there in 1st object, you cannot set 'rights' to any value including blank even having 'rights' attribute is not valid.
}
]
}
以下是我需要整理的if-else条件:
//Assuming admin object exist with rights....
if( type == admin && rights != ""){
if(type == guest && rights attribute is there && rights != ""){
//The 'guest' object will always be there....
//error: guest 'rights' cannot have a value if type is 'admin' and rights is 'all' or any other value.
}
}else{
//Assuming mandatory guest object exist with rights....
if(guest.rights does not exist OR guest.rights == "")
//Error: 'rights' is MANDATORY attribute in guest block and error if its empty
else
//Everything is fine
}
还有什么方法可以检查数组中是否只有一对特定类型的对象?
例如:只有一个“来宾”和“管理员”类型。错误,如果存在多个类型的“来宾”或“管理员”
//完整示例
{
[
{
"type":"superadmin",
"hyperLink": "http://www.superadmin.com"
},
{
"type":"admin",
"hyperLink": "http://www.admin.com",
"rights":"all"
},
{
"type":"user",
"hyperLink": "http://www.user.com"
},
{
"type":"guest",
"hyperLink": "http://www.guest.com"
}
]
}
使用JSON模式执行此操作似乎有点棘手,但这是可能的 您需要能够有条件地检查负面条件 因此,您需要结合使用
if
和then
,以及not
首先是条件:如果有管理员用户。使用if
,我们可以有条件地应用进一步的检查规则
接下来,检查:来宾用户不能拥有权限
则在通过验证时应用。然后,我们需要使用not
来否定检查来宾是否拥有权限
您可以通过使用提供的示例预期无效JSON数据正确地看到验证失败的情况(该链接预先加载了此架构和您提供的实例数据。它在浏览器中使用AJV。)
更新:我已经更新了模式以满足您的其他要求。
我还更新了上面的演示链接
模式现在只允许admin在存在admin时拥有权限,并且如果存在admin,则其他用户类型可能没有权限。此外,数组中的一项必须具有权限(根据需要)
我认为仅使用纯JSON模式就可以做到这一点。让Clarify想想,你的阵列是否只有两个对象,或者它们可能有两个以上的对象?顺序是已知的还是未知的(不是问题,但解决方案可能不同)?事实上,这没有什么区别。为您找到了一个解决方案。该数组可以有更多的对象作为更新的问题。如果我们能处理好订单,那就好了。正如您所提到的,这可能很棘手,这是ajv自定义验证可以提供帮助的一种方式吗?谢谢你的回复啊,那么,如果有一个管理员,那么其他类型就没有权限了?那么现在的关系是“admin”类型和“guest”类型之间的关系。我不知道今后这种关系是否会有任何变化。如何进行自定义ajv验证以适应这种复杂性的任何近期模式更改如何使其适用于更新的模式,其中我们有2个附加属性,“items”作为数组键,多个枚举类型作为对象。此外,“rights”是必填属性。请查看问题中更新的模式。我已更新了答案。现在,如果存在admin,则其他用户可能没有权限,并且阵列中至少有一项必须具有权限。感谢您澄清此问题。然而,现在我有了一个最终更新的模式,我尝试使用您的方法,但最终它不起作用,可能是因为模式中的更改。我知道我要求很多,但有人能帮我吗?我已经更新了[09/29]**********项下问题的详细信息。谢天谢地,不断改变你的问题被认为是不好的方式。这变成了一个不同的问题,因为第一部分得到了回答。如果你有另一个更复杂的问题,最好问另一个问题。您添加的内容与原始问题非常不同。问题已更新为原始形式,以保持解决方案的相关性。
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"if": {
"contains": {
"required": [
"type"
],
"properties": {
"type": {
"const": "admin"
}
}
}
},
"then": {
"not": {
"contains": {
"required": [
"type",
"rights"
],
"properties": {
"type": {
"not": {
"const": "admin"
}
}
}
}
}
},
"contains": {
"type": "object",
"required": ["rights"]
},
"items": {
"type": "object",
"properties": {
"type": {
"enum": [
"guest",
"admin"
]
},
"rights": {
"type": "string"
},
"hyperLink": {
"type": "string",
"format": "uri"
}
}
}
}