用于强制执行数组内容的JSON模式

Daw*_*son 15 arrays validation schema json jsonschema

大家好,提前谢谢.

我试图创建一个JSON模式来强制数组包含一个A和B对象和NC对象,其中A和B是C对象,N是包含在0和无穷大之间的整数.

因此:

[A, B] [A, B, C1] [A, B, C1, .., CN]

但是都是有效的:

[A] [A, C1] [A, C1, .., CN]

无效的.

为清楚起见,A和B必须存在.C对象是可选的,但您可以拥有任意数量的对象.

C对象模式:


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

  "type": "object",
  "required": ["id", "name"],

  "properties": {
    "id": {
      "type": "integer"
    },
    "name": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
Run Code Online (Sandbox Code Playgroud)

所以C对象是任何有效的JSON对象,只包含属性"id"和"name",其中"id"是一个整数,"name"是一个字符串.

A和B对象模式:


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

  "type": "object",
  "required": ["id", "name"],

  "properties": {
    "id": {
      "type": "integer"
    },
    "name": {
      "type": "string",
      "enum": ["A"]
    }
  },
  "additionalProperties": false
}
Run Code Online (Sandbox Code Playgroud)

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

  "type": "object",
  "required": ["id", "name"],

  "properties": {
    "id": {
      "type": "integer"
    },
    "name": {
      "type": "string",
      "enum": ["B"]
    }
  },
  "additionalProperties": false
}
Run Code Online (Sandbox Code Playgroud)

A和B对象与C对象的不同之处在于强制执行名称值.A对象的名称值必须是字段枚举中包含的值,其中枚举包含单个值.

我迄今为止最完整的架构是:


{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "To Date Solution",
  "description": "So far this is the most complete attempt at enforcing values to be contained within a JSON structure using JSON schemas.",

  "type": "array"
  "items": {
    "allOf": [
      {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "C Object",

        "type": "object",
        "required": ["id", "name"],

        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "additionalProperties": false
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

这强制了包含在其中的所有对象必须是C类型,A和B是,但我不确定如何强制执行至少单个A和B实例包含在我的数组中.

clo*_*eet 12

您正在寻找的是"元组打字".

如果items关键字的值是数组,则数组数据中的项必须与相应位置中的模式匹配.附加项目(超过最后一个索引)匹配additionalItems(或者如果additionalItems是,则不允许false).

所以,大致你想要的是:

{
    "type": "array",
    "items": [
        {"$ref": "#/definitions/itemTypeA"},
        {"$ref": "#/definitions/itemTypeB"}
    ],
    "additionalItems": {"$ref": "#/definitions/itemTypeC"},
    "definitions": {
        ... actual definitions for A/B/C ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想确保 A和B存在,那么你只需指定一个最小长度minItems,所以至少有两个项目(由于"元组输入",必须与A和B匹配).

(这也假设A和B是数组中的第一项.如果这不是你想要的,那么它会变得有点复杂 - 尽管有一个contains为v5提出的关键字可以很好地处理它.)

稍微更详细的现场演示:

  • 如果您希望它与位置无关,您可以*在v4中执行[相当可怕的事情](https://gist.github.com/anonymous/7359001).但是,我一般不会建议它,因为它很难阅读/理解. (2认同)
  • 还值得注意的是,对于 v4 hack 和 v5 `contains` 关键字,约束都是“至少 ** ** 一个” - 而 `additionalItems` 不适用。对于 v5,有 [一种解决方法](https://gist.github.com/anonymous/7359101) 来指定一个。 (2认同)