JSON架构嵌套If Then

anauzrmj  于 2022-11-26  发布在  其他
关注(0)|答案(1)|浏览(145)

我似乎找不到在枚举上应用多个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
  }
}

它仍然成功。
我还没有设法让嵌套的if/then/else/if/then/else工作。
我如何执行一个检查,其中我有一组属性为每个type,你不能混合他们?这是实际上可能的,或者我应该改变我的设计。

von4xj4u

von4xj4u1#

首先,你可以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子模式。它没有说如果typenota要验证什么,所以它通过了。如果你在上面加上一个else:false,它会更符合你的想法,但我鼓励你们换个Angular 思考。
使用oneOf * 或 * if/then/else,但不要同时使用这两种格式。我建议将子模式改为使用以下格式:

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

这Assertoption1是必需的,并且必须是布尔值,并且Asserttype=a。如果type而不是a,则此模式将失败,这正是您所希望的。
This answer更详细地描述了您需要执行的操作。

相关问题