如何基于Type对象属性的值来验证某些对象属性的存在和值?

时间:2019-04-18 22:49:18

标签: json jsonschema

我正在尝试验证比下面更复杂的JSON,但是希望这个更简单的示例可以清楚地说明问题。

在更复杂的架构中,我需要具有一个对象数组,其中:

  • 所有对象都具有一组相同的属性,例如名称类型
  • 类型属性是允许的对象类型的枚举,例如“全职”,“承包商”
  • 基于 Type 属性的值,定义了其他每个类型的属性集。例如,“全职”员工具有必需的 Salary 属性和可选的 Email 属性,而“承包商”员工具有费率属性是必需的,没有可选的其他属性。
  • 每个对象中都应只允许定义的属性
  • 每个对象的必需属性可能包括所有对象共有的属性,例如 Name Type ,以及特定于一种类型的对象的属性,例如作为薪金

这似乎应该是一个普遍的问题,但是到目前为止,我还没有找到与我想做的事情完全匹配的东西。这些很接近,但是我无法确切地知道如何将它们应用于和/或哪种方法最适合我的用例,因此希望对这一领域有更好了解的人可以提供帮助:

特别是,不清楚common和per-object属性中的required和extraProperties关键字如何工作。

到目前为止,我已经有了模式,并且有不必要的重复:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "$ref": "#/definitions/Employee"
  },
  "definitions": {
    "Employee": {
      "type": "object",
      "oneOf": [{
        "properties": {
          "Name": { "type": "string" },
          "Type": { "type": "string", "enum": [ "Full-Time" ] },
          "Salary": { "type": "integer" },
          "Email": { "type": "string" }
        },
        "required": [ "Name", "Type", "Salary" ],
        "additionalProperties": false
      },
      {
        "properties": {
          "Name": { "type": "string" },
          "Type": { "type": "string", "enum": [ "Contractor" ] },
          "Rate": { "type": "number" }
        },
        "required": [ "Name", "Type", "Rate" ],
        "additionalProperties": false
      }]
    }
  }
}

要验证此数据:

[
  { "Name": "Good First Employee",    "Type": "Full-Time",  "Salary": 100000, "Email": "first.employee@example.com"  },
  { "Name": "Good Second Employee",   "Type": "Full-Time",  "Salary":  90000 },
  { "Name": "Good First Contractor",  "Type": "Contractor", "Rate": 20.00 },
  { "Name": "Good Second Contractor", "Type": "Contractor", "Rate": 25 },
  { "Name": "Bad First Person",       "Type": "Unknown",    "Salary":  90000 },
  { "Name": "Bad Third Employee",     "Type": "Full-Time" },
  { "Name": "Bad Fourth Employee",    "Type": "Full-Time",  "Rate": 49.00 },
  { "Name": "Bad Fifth Employee",     "Type": "Full-Time",  "Salary": 100000, "Phone": "123-123-1234" },
  { "Name": "Bad Second Person" }
]

对于以上数据,具有名称(以“ Good”开头)的对象有效。其余以“错误”开头的内容无效:

  • 第一人称错误-类型无效
  • 糟糕的第三雇员-薪水缺失
  • 第四雇员差-缺少工资,该雇员的费率无效
  • 第五雇员差-雇员的电话无效
  • 第二人称-缺少类型(常见字段)

某些方法可行,但是带有过多的错误消息,但不能清楚地指出问题出在哪里。

1 个答案:

答案 0 :(得分:0)

这是一个常见问题。不幸的是,您不必要的重复是实现7草案JSON架构所需的唯一方法。

我们(JSON Schema核心团队)在为draft-8添加新关键字方面做了很多工作,但是尚未发布/完成。 https://github.com/json-schema-org/json-schema-spec/issues/556-unevaluatedProperties

链接的问题包括很多细节,其中包括一个示例,说明OpenAPI规范存在相同的问题,并且使用了大量重复数据删除技术。新关键字消除了很多重复。