【问题标题】:JSON Schema Nested If ThenJSON Schema 嵌套 If Then
【发布时间】:2019-08-20 18:16:07
【问题描述】:

我似乎找不到在枚举上应用多个 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 的属性集,而您不能将它们混合在一起?这真的可能吗,还是我应该改变我的设计。

【问题讨论】:

    标签: json schema jsonschema


    【解决方案1】:

    首先,您可以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 时实际上不会失败。它只是说如果 type=a,应用then 子模式。如果typenot 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 更详细地描述了您需要做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      • 2023-02-01
      • 1970-01-01
      相关资源
      最近更新 更多