数组中某些对象属性的JSON模式条件检查 [英] JSON schema conditional check on certain object attribute within an array
问题描述
我想通过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.
}
]
}
这是我需要解决的其他条件:
//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 Schema进行此操作似乎有些棘手,但有可能.
您需要能够有条件地检查否定条件.
因此,您需要将if
和then
与not
结合使用.
首先要满足的条件:如果有管理员用户.然后,使用if
,我们可以有条件地应用其他检查规则.
下一步,检查:来宾用户不能拥有rights
.
if
通过验证时,将应用 then
.然后,我们需要使用not
取消对guest
是否具有rights
的检查.
可以看到这与实施例正确地验证失败预期您使用的 https://jsonschema.dev (链接已预加载此架构和您提供的实例数据.在btw中使用AJV.)
更新:我已经更新了架构以满足您的其他要求. 我还更新了上面的演示链接.
现在,该架构仅允许在具有admin的情况下让admin拥有权限,而在具有admin的情况下,其他任何用户类型都不能具有权限.另外,数组中的一项必须具有权限(根据需要).
{
"$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"
}
}
}
}
What I want to do either via AJV - JSON Schema validation or Custom Keywords (preferably I would go with this): The Array can have 1 or 2 JSON objects with type as 'admin' and 'guest'. The "type":"guest" object will always be there and "type":"admin" object is optional.
Extra Notes:
-The object itself may contain addition attributes and nested objects, in future
-The other valid enums aresuperadmin, admin,user and guest
-The type sequence in array is: superadmin, admin,user and guest. Is it possible to check the sequence? (although its optional)
-The 'guest' type object will always be there and there will be a unique type of object. If any re-occurence any object type (e.g. superadmin, admin,user and guest) then its an error
//Here is the schema:
{
"type": "object",
"properties": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "enum": ["guest", "admin"]
},
"rights": {"type": "string"},
"hyperLink": {"type": "string", "format": "uri"}
}
}
}
}
I need to add 'checkTypeAndValue' flag somewhere in the json so that I can grab the complete JSON object and the corresponding attributes to do a programmatic check?
const checkTypeAndValue = function (schema, completeJSONObj) {
//
};
ajv.addKeyword('checkTypeAndValue', {
validate: checkTypeAndValue,
errors: true
});
and here are some valid and invalid examples:
/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.
}
]
}
Here is the if else condition that I need to sort out:
//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
}
Also is there any way by which we can check in an array that there will be only one pair of object of certain type? For example: only one 'guest, 'admin' type. Error, if there are more than one type of 'guest' or 'admin'
//Complete example
{
[
{
"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"
}
]
}
It may seem a little tricky to do this with JSON Schema, but it is possible.
You need to be able conditionally check a negative condition.
So, you'll need to use a combination of if
and then
, with not
.
First the condition: if there's an admin user. Using if
, we can then conditionally apply the further checking rule.
Next, the check: guest user cannot have rights
.
then
is applied when if
passes validation. We then need to negate a check that a guest
has rights
, using not
.
You can see this correctly failing validation with the example expected invalid JSON data you provided using https://jsonschema.dev (link is pre-loaded with this schema and your provided instance data. It uses AJV in browser btw.)
Update: I've updated the schema to meet your additional requirements. I've also updated the demo link above.
The schema now only allows admin to have rights if admin is present, and no other user type may have rights if admin is present. Also one item in the array must have rights (as you required).
{
"$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"
}
}
}
}
这篇关于数组中某些对象属性的JSON模式条件检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!