对象属性取决于字段的值

时间:2017-07-06 15:36:32

标签: json jsonschema

我为文件创建一个JSON模式,如下所示:

{
  "name": "My project",
  "debug": {
    "actions": [
      {
        "type": "type 1",
        "options": {
          "option 1 for type 1": "my-project",
          "option 2 for type 1": "whatever"
        }
      },
      {
        "type": "type 2",
        "options": {
          "option 1 for type 2": "my-project",
          "option 2 for type 2": "whatever",
          "option 3 for type 2": "whoohooo"
        }
      }
    ]
  }
}

基本上,"动作"可以包含所有具有"类型的对象"属性并基于此属性的值,选项应显示特定选项。总之,我希望能够进行某种映射,例如:

"type 1": "#/definitions/type1Options",
"type 2": "#/definitions/type2Options"

这可能吗?

1 个答案:

答案 0 :(得分:1)

是的,您可以使用暗示基于字段的值应用架构。从两个模式开始。让我们将它们称为A和B.如果字段是必需值,则模式A验证为true(示例:类型为类型1)。如果第一个模式为true,则模式B应该验证为true(示例:具有特定选项)。

使用这两个模式,您可以创建一个语句,以根据模式A有条件地应用模式B.要么A不验证为true,要么B验证为true。这被称为暗示。

架构有点复杂,但它有效。

{
  "type": "object",
  "properties": {
    "type": { "enum": ["type 1", "type 2"] },
    "options": {
      "type": "object",
      "properties": {
        "option 1 for type 1": { "type": "string" },
        "option 2 for type 1": { "type": "string" },
        "option 1 for type 2": { "type": "string" },
        "option 2 for type 2": { "type": "string" },
        "option 3 for type 2": { "type": "string" }
      }
    }
  },
  "allOf": [
    { "$ref": "#/definitions/type-1" },
    { "$ref": "#/definitions/type-2" }
  ],
  "definitions" {
    "type-1": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/type-is-type-1" } },
        { "$ref": "#/definitions/type-1-options" }
      ]
    },
    "type-2": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/type-is-type-2" } },
        { "$ref": "#/definitions/type-2-options" }
      ]
    },
    "type-is-type-1": {
      "properties": {
        "type": { "enum": ["type 1"] }
      }
    },
    "type-is-type-2": {
      "properties": {
        "type": { "enum": ["type 2"] }
      }
    },
    "type-1-options": {
      "properties": {
        "options": {
          "required": ["option 1 for type 1", "option 2 for type 1"]
        }
      }
    },
    "type-2-options": {
      "properties": {
        "options": {
          "required": ["option 1 for type 2", "option 2 for type 2", "option 3 for type 2"]
        }
      }
    }
  }
}