javascript - JSON 架构 : "allof" with "additionalPro

假设我们有模式跟随模式(来自教程 here):

{
  "$schema": "http://json-schema.org/draft-04/schema#",

  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city":           { "type": "string" },
        "state":          { "type": "string" }
      },
      "required": ["street_address", "city", "state"]
    }
  },

  "type": "object",

  "properties": {
    "billing_address": { "$ref": "#/definitions/address" },
    "shipping_address": {
      "allOf": [
        { "$ref": "#/definitions/address" },
        { "properties":
          { "type": { "enum": [ "residential", "business" ] } },
          "required": ["type"]
        }
      ]
    } 

  }
}

这是一个有效的实例:

{
      "shipping_address": {
        "street_address": "1600 Pennsylvania Avenue NW",
        "city": "Washington",
        "state": "DC",
        "type": "business"
      }
}

我需要确保 shipping_address 的任何附加字段均无效。我知道为此目的存在 additionalProperties 应该设置为“false”。但是当我设置 "additionalProprties":false 如下:

"shipping_address": {
          "allOf": [
            { "$ref": "#/definitions/address" },
            { "properties":
              { "type": { "enum": [ "residential", "business" ] } },
              "required": ["type"]
            }
          ],
          "additionalProperties":false
        } 

我收到一个验证错误(检查 here):

[ {
  "level" : "error",
  "schema" : {
    "loadingURI" : "#",
    "pointer" : "/properties/shipping_address"
  },
  "instance" : {
    "pointer" : "/shipping_address"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "additional properties are not allowed",
  "unwanted" : [ "city", "state", "street_address", "type" ]
} ] 

问题是:我应该如何限制 shipping_address 部分的字段?提前致谢。

最佳答案

[此处是 v4 验证规范草案的作者]

您偶然发现了 JSON Schema 中最常见的问题,即它根本无法按照用户期望的方式进行继承;但同时它也是它的核心功能之一。

当你这样做时:

"allOf": [ { "schema1": "here" }, { "schema2": "here" } ]

schema1schema2 彼此了解;它们在自己的上下文中进行评估。

在很多人遇到的场景中,您希望 schema1 中定义的属性对 schema2 是已知的;但事实并非如此,而且永远不会。

这个问题是我为草案 v5 提出这两个提案的原因:

  • strictProperties ,
  • merge .

您的 shipping_address 架构将是:

{
    "merge": {
        "source": { "$ref": "#/definitions/address" },
        "with": {
            "properties": {
                "type": { "enum": [ "residential", "business" ] }
            }
        }
    }
}

以及在 address 中将 strictProperties 定义为 true


顺便说一句,我也是你所指网站的作者。

现在,让我回到草稿 v3。 Draft v3 确实定义了 extends,它的值要么是一个模式,要么是一个模式数组。通过这个关键字的定义,这意味着实例必须对当前模式有效extends中指定的所有模式;基本上,draft v4 的 allOf 是 Draft v3 的 extends

考虑一下(草案 v3):

{
    "extends": { "type": "null" },
    "type": "string"
}

现在,那个:

{
    "allOf": [ { "type": "string" }, { "type": "null" } ]
}

它们是一样的。还是那样?

{
    "anyOf": [ { "type": "string" }, { "type": "null" } ]
}

还是那个?

{
    "oneOf": [ { "type": "string" }, { "type": "null" } ]
}

总而言之,这意味着草案 v3 中的 extends 从未真正做到人们期望的那样。在草案 v4 中,明确定义了 *Of 关键字。

但是到目前为止,您遇到的问题是最常见的问题。因此,我的建议将一劳永逸地消除这种误解的根源!

关于javascript - JSON 架构 : "allof" with "additionalProperties",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22689900/

相关文章:

java - jackson JSON : get node name from json-tree

javascript - 从名称、值 JSON 数组中获取一项

jquery - JSON解析错误语法错误意外结束输入

java - 对象数组与对象对象

jquery - 将json加载到变量中

json - 如何加密散列 JSON 对象?

java - 不支持 Spring Rest POST Json RequestBody 内容类型

python - 在 json 中发送 NaN

java - 从 JSONArray 转换为 String 然后再转换回来

ios - 如何在 Swift 中组合两个 Dictionary 实例?