JSON 使用条件关键字的架构交叉键约束支持

JSON Schema cross key constraint support using conditonal keywords

我想表达包含交叉键条件的模式的条件验证。在 JSON 模式中是否支持使用可用的条件关键字 (allOf/anyOf/if/then/else)

JSON 架构:

{
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "x": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "value": {
                    "type": "string"
                }
            }
        },
        "y": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
                "key1": {
                    "type": "string",
                    "enum": ["a", "b", "c", "d", "e"]
                },
                "key2": {
                    "type": "string",
                    "enum": ["x", "y", "m", "n", "r", "s"]
                }
            },
            "anyOf": [{
                    "allOf": [{
                            "if": {
                                "properties": {
                                    "key1": {
                                        "enum": ["a", "b"]
                                    }
                                }
                            },
                            "then": {
                                "properties": {
                                    "key2": {
                                        "enum": ["x", "y"]
                                    }
                                }
                            }
                        },
                        {
                            "if": {
                                "x": {
                                    "properties": {
                                        "value": {
                                            "const": "myVal"
                                        }
                                    }
                                }
                            },
                            "then": {
                                "properties": {
                                    "key2": {
                                        "enum": ["x", "y"]
                                    }
                                }
                            }
                        }
                    ]
                },
                {
                    "if": {
                        "properties": {
                            "key1": {
                                "enum": ["c", "d"]
                            }
                        }
                    },
                    "then": {
                        "properties": {
                            "key2": {
                                "type": "string",
                                "enum": ["m", "n"]
                            }
                        }
                    }
                }
            ]
        }
    }
}

示例 JSON 实例如下所示

{
    "x": {
        "value": "myVal"
    },
    "y": {
        "key1": "a",
        "key2": "x"
    }
}

我要表达的条件是以下2个条件

  1. If (x.value == "myVal" AND (y.key1 == "a" OR y.key1 == "b ") then y.key2 应该只有 "x" 或 "y"
    (或)

  2. If ( y.key1 == "c" OR y.key1 == "d") 然后 y.key2 应仅包含“m”或“n”。

    (或)

  3. y.key2 可以采用 y.key2 属性.

    中定义的任何允许的枚举值

我使用 JSON 架构的条件不起作用。我尝试使用 https://www.jsonschemavalidator.net/ 进行验证。

任何帮助将不胜感激:)

谢谢

所以我认为这是最好忘记 if/then/else 关键字并只在 [=13 中定义好的状态的情况之一=]. (我建议 oneOf 而不是 anyOf 因为 这些状态中只有一个 应该匹配。)

所以对于您的架构,您需要一个

  1. 全部
    • x.value == "myVal"
    • y.key1 in ["a", "b"]
    • y.key2 in ["x", "y"]
  2. 全部
    • y.key1 in ["c", "d"]
    • y.key2 in ["m", "n"]
  3. 全部
    • 没有
      • 其中之一
        • 全部
          • x.value == "myVal"
          • y.key1 in ["a", "b"]
        • y.key1 in ["c", "d"]
    • true(或者 {} 如果你是 pre-draft-6)

看来您已经解决了#1 和#2;只需删除条件逻辑。起作用的是#3 中的 NOT。这里我们说的是,如果#1 的条件为假 并且 的条件为假,#2 的条件为假,那么枚举中已经为 y.key2 定义的任何值都可以。

我们必须明确表示我们不想要 #1 和 #2 的条件的原因是没有它们,我们只有一个 true 模式,它允许一切(以前没有约束).

现在这里的另一个陷阱是你在你的一个条件中使用了 x,但是你的 anyOf 子模式在 y 的定义之下,所以它不能'根本看不到 x。要解决此问题,您需要将该子模式移动到根目录,作为 properties 的同级。在这里它可以查看整个实例,而不仅仅是 y 属性.

中的值