简体   繁体   English

如果那么JSON Schema嵌套

[英]JSON Schema Nested If Then

I cannot seem to find a working way of applying multiple if/then logic on an enum. 我似乎找不到在枚举上应用多个if / then逻辑的工作方式。

anyOf doesnt apply the conditional logic, but instead it says if any of them match then thats good. anyOf不应用条件逻辑,但是它表示如果它们中的任何一个匹配那么那么好。

allOf again doesnt apply the conditional logic but tests a superset of the properties/required fields. allOf再次不应用条件逻辑,但测试属性/必填字段的超集。

Here is a JSON Schema example: 这是一个JSON Schema示例:

{
  "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": {}
          }
        }
      ]
    }
  }
}

If you validate against this JSON: 如果您对此JSON进行验证:

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

It fails because option2 is required. 它失败,因为需要option2

If you change it to anyOf then it succeeds, but if you change the JSON to be invalid: 如果将其更改为anyOf则会成功,但如果将JSON更改为无效:

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

It still succeeds. 它仍然成功。

I havent managed to get nested if/then/else/if/then/else working either. 我没有设法嵌套如果/ then / else / if / then / else也工作。

How can i perform a check where I have set of properties for each type and you cannot intermingle them? 如何检查每种type的属性集,并且不能将它们混合在一起? Is this actually possible, or should I just change my design. 这实际上是可行的,还是我应该改变我的设计。

First, you can test your schemas here . 首先,您可以在此处测试您的模式 There are several of these sites across the internet. 互联网上有几个这样的网站。

Second, the if / then / else construct was introduced to replace a oneOf for these kind of enum scenarios, not be combined with it. 其次,引入了if / then / else构造来替换这些枚举场景的oneOf ,而不是与它结合。

This subschema 这个子模式

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

doesn't actually fail when type is not a . type不是a时,实际上不会失败。 It merely says that if type=a , apply the then subschema. 它只是说如果 type=a ,则应用then子模式。 It doesn't say anything about what do validate if type is not a , so it passes. 如果type 不是 a ,它没有说什么验证,所以它通过了。 If you add an else:false to this, it'll be more in line with what you're thinking, but I encourage you to think about it differently. 如果你添加一个else:false ,它会更符合你的想法,但我鼓励你以不同的方式思考它。

Use oneOf or if / then / else , but not both. 使用oneOf if / then / else ,但不能同时使用两者。 I suggest changing your subschemas to use this format: 我建议更改您的子模式以使用此格式:

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

This asserts that option1 is required and must be a boolean, and that type=a . 这断言option1是必需的,并且必须是布尔值,并且type=a If type is not a , this schema fails, which is what you want. 如果type 不是 a ,则此架构将失败,这就是您想要的。

This answer describes what you need to do in a bit more detail. 这个答案更详细地描述了您需要做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM