数组中某些对象属性的JSON模式条件检查 [英] JSON schema conditional check on certain object attribute within an array

查看:73
本文介绍了数组中某些对象属性的JSON模式条件检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过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进行此操作似乎有些棘手,但有可能.

您需要能够有条件地检查否定条件.

因此,您需要将ifthennot结合使用.

首先要满足的条件:如果有管理员用户.然后,使用if,我们可以有条件地应用其他检查规则.

下一步,检查:来宾用户不能拥有rights.

if通过验证时,将应用

then.然后,我们需要使用not取消对guest是否具有rights的检查.

可以看到这与实施例正确地验证失败预期您使用的

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆