JSON Schema需要特定的数组元素

时间:2017-11-17 10:28:41

标签: json jsonschema

我将属性列表定义为json schema:

{
  "$schema": "http://json-schema.org/schema#",
  "type": "object",


  "definitions": {

    "attribute": {
      "type": "object",
      "properties": {
        "symbolic-name": { "type":"string"},
        "value": { "type":"string"}
      },
      "required": ["symbolic-name", "value"]
    },

    "displayname": {
      "type": "object",
      "properties": {
        "symbolic-name": {"enum":["displayName"]},
        "value": { "type":"string"}
      },
      "required": ["symbolic-name", "value"]
    }

  },

  "properties": {
    "attributes":{
      "type": "array",
      // This is the crucial point:
      "items": {"oneOf": [
               {"$ref": "#/definitions/attribute"},
               {"$ref": "#/definitions/displayname"}
      ]},
      "uniqueItems": true
    }
  }
}

我想要求列表中只有一个属性symbolic-name="displayName"

有效的数据对象是:

{
  "attributes":[
    {"symbolic-name": "displayName", "value": "Display Name"},
    {"symbolic-name": "somethingElse", "value": "value1"}
    {"symbolic-name": "somethingElse", "value": "value2"}
  ]
}

现在,由于displayName属性不仅匹配“oneOf”,而且两个限制都匹配,因此无法验证。我无法将其更改为“allOf”,因为displayName旁边的所有其他属性将不再匹配。

1 个答案:

答案 0 :(得分:2)

为了使"oneOf"能够正常工作,您需要使用"属性"和" displayname"模式是相互排斥的 - 如同书写的,任何有效的"显示名称"也是一个有效的"属性"。我们可以通过排除" displayName"作为"属性"的有效符号名称:

"symbolic-name": {
    "type": "string",
    "not": {"enum": ["displayName"]}
}

现在元素的符号名称为" displayName"可以匹配" displayname"定义,但永远不会匹配"属性"定义

你问题的另一部分是关于只有一个" displayname"在你的数组中。这比较棘手。它还取决于您正在使用的JSON Schema草稿。实施了4和6,并且星期一发布了7个 - 只是声明"$schema": "http://json-schema.org/schema#"表示您使用的是最新的,即7个。我建议使用$schema的特定草稿而不是非{ - 编号可能会更改,恕不另行通知。

如果你可以要求" displayname"要成为数组的第一个元素,那么这适用于任何草稿(你甚至不需要"oneOf"):

"items": [{"$ref": "#/definitions/displayname"}],
"additionalItems": {"$ref": "#/definitions/attribute"}

请注意"items"是一个数组。这意味着第一项必须是" displayname"除了第一项之外的所有其他项目必须是"属性" s。

如果你想允许" displayname"在任何位置,这都比较难。从草案06开始,有"contains",这需要至少一个项目来匹配给定的模式。但是没有简单的方法可以说"最多只有一个项目"。但是,建议将"minContains""maxContains"用于草案-08:https://github.com/json-schema-org/json-schema-spec/issues/441

目前,希望您可以要求第一个位置为" displayname",因为这将适用于所有草稿。