JSON 模式对数组中某些对象属性进行条件检查

标签 json jsonschema json-schema-validator ajv

我想通过 AJV - JSON 架构验证或自定义关键字(我最好选择这个)执行以下操作:数组可以有 1 或 2 个类型为“admin”和“guest”的 JSON 对象。 "type":"guest"对象将始终存在,而 "type":"admin"对象是可选的。

附加说明:

-将来,对象本身可能包含附加属性和嵌套对象

-其他有效枚举是superadmin、admin、user 和 guest

-数组中的类型顺序为:superadmin、admin、user、guest。是否可以检查顺序? (尽管它是可选的)

-“ guest ”类型的对象将始终存在,并且会有唯一类型的对象。如果任何对象类型(例如 super 管理员、管理员、用户和访客)再次出现,则出现错误

//这是架构:

{
"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
}

还有什么方法可以让我们检查数组中是否只有一对特定类型的对象? 例如:只有一种“访客”、“管理员”类型。如果有不止一种类型的“ guest ”或“管理员”,则会出错

//完整示例

{
  [
    {
      "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 来做到这一点似乎有点棘手,但这是可能的。

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

因此,您需要结合使用 ifthen 以及 not

首先条件:是否有管理员用户。使用 if,我们可以有条件地应用进一步的检查规则。

接下来,检查: guest 用户不能拥有权限

thenif 通过验证时应用。然后,我们需要使用 not 来取消对 guest 拥有 rights 的检查。

您可以通过使用 https://jsonschema.dev 提供的预期无效 JSON 数据的示例看到此验证正确失败。 (链接已预先加载此架构和您提供的实例数据。顺便说一句,它在浏览器中使用 AJV。)


更新:我已更新架构以满足您的其他要求。 我还更新了上面的演示链接。

该架构现在仅允许管理员在存在管理员的情况下拥有权限,并且如果存在管理员,则其他用户类型都不能拥有权限。此外,数组中的一项必须具有权限(根据您的需要)。

{
  "$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 模式对数组中某些对象属性进行条件检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58135703/

相关文章:

json - 尝试读取 JSON 时函数体外部的非声明语句

json - 使用 Azure 逻辑应用将 Json 数据发布到 Facebook 时间线

arrays - JSON 模式中的多值枚举?

java - 是否有通过 Java 从 XML 模式生成 JSON 模式的工具?

json - 如何在 json 模式中创建模式引用的嵌套列表(数组)

javascript - AJV 多级/嵌套 JSON 模式验证

javascript - ajax将json值传递给html header 类

javascript - 将 PHP 中的 JSON 数据拆分为 JavaScript 中的三个数组

jsonschema - 互斥属性组

python - json schema Draft 7 python 中的多种自定义类型