如果是,则嵌套JSON模式

时间:2019-03-29 18:33:17

标签: json schema jsonschema

我似乎找不到在枚举上应用多个if / then逻辑的可行方法。

anyOf不应用条件逻辑,而是说如果它们中的任何一个匹配,那就很好。

allOf再次不应用条件逻辑,而是测试属性/必填字段的超集。

这是一个JSON模式示例:

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "type"
  ],
  "properties": {
    "type": {
      "$id": "#/properties/type",
      "enum": [
        "a",
        "b",
        "c"
      ],
      "title": "The Type"
    },
    "options": {
      "$id": "#/properties/options",
      "type": "object",
      "title": "The Options Schema",
      "oneOf": [
        {
          "if": { "properties": { "type": { "const": "a" } }
          },
          "then": {
            "required": [ "option1" ],
            "properties": {
              "option1": {
                "$id": "#/properties/options/properties/option1",
                "type": "boolean",
                "title": "The option1 Schema"
              }
            }
          }
        },
        {
          "if": { "properties": { "type": { "const": "b" } }
          },
          "then": {
            "required": [ "option2" ],
            "properties": {
              "option2": {
                "$id": "#/properties/options/properties/option2",
                "type": "boolean",
                "title": "The option2 Schema"
              }
            }
          }
        },
        {
          "if": { "properties": { "type": { "const": "c" } }
          },
          "then": {
            "required": [],
            "properties": {}
          }
        }
      ]
    }
  }
}

如果您使用此JSON进行验证:

{
  "type": "a",
  "options": {
    "option1": true
  }
}

失败,因为需要option2

如果将其更改为anyOf,则它将成功,但是如果将JSON更改为无效:

{
  "type": "a",
  "options": {
    "option2": false
  }
}

它仍然成功。

如果/ then / else / if / then / else都不能工作,我还没有设法嵌套。

如何检查每个type的属性集,而您不能将它们混合?这实际上可行吗,还是我应该更改设计。

1 个答案:

答案 0 :(得分:0)

首先,您可以test your schemas here。互联网上有几个这样的网站。

其次,引入了if / then / else构造,以代替这些枚举方案的oneOf,而不是与之结合。

此子模式

"if": { "properties": { "type": { "const": "a" } } },
"then": {
  "required": [ "option1" ],
  "properties": {
    "option1": {
      "$id": "#/properties/options/properties/option1",
      "type": "boolean",
      "title": "The option1 Schema"
    }
  }
}
type不是a时,

实际上并没有失败。它只是说 if type=a,应用then子模式。它没有说明type是否不是 a时如何验证,因此它可以通过。如果您为此添加else:false,它将更符合您的想法,但我鼓励您以不同的方式考虑它。

使用oneOf if / then / else,但不能同时使用。我建议您更改子计划以使用以下格式:

{
  "properties": {
    "type": { "const": "a" },
    "option1": {
      "$id": "#/properties/options/properties/option1",
      "type": "boolean",
      "title": "The option1 Schema"
    }
  },
  "required": [ "option1" ],
}

这断言option1是必需的,并且必须是布尔值,并且是type=a。如果type 不是 a,则此架构失败,这就是您想要的。

This answer详细介绍了您需要做的事情。