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



我想表达对包含交叉键条件的模式的条件验证。在具有可用条件关键字(allOf/anyOf/if/then/else(的 JSON 架构中是否支持此功能

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个条件

如果 (x.value == "myVal" AND (y.key1 == "a" OR y.key1
  1. == "b"(y.key2 应该只有 "x" 或 "y">
    (OR(

  2. 如果( y.key1 == "c" OR y.key1 == "d"(y.key2 应该只包含 "m" 或 "n"。

    (或(

  3. y.key2
  4. 可以采用 y.key2 属性中定义的任何允许的枚举值。

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

任何帮助将不胜感激:)

谢谢

所以我认为这是最好忘记if/then/else关键字并只定义oneOf中的良好状态的情况之一。 (我建议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(如果您已预选 6{}(

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

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

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

最新更新