我想表达对包含交叉键条件的模式的条件验证。在具有可用条件关键字(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== "b"(则y.key2 应该只有 "x" 或 "y">
(OR(如果( y.key1 == "c" OR y.key1 == "d"(则y.key2 应该只包含 "m" 或 "n"。
(或(
y.key2可以采用 y.key2 属性中定义的任何允许的枚举值。
我使用 JSON 架构的条件不起作用。我尝试使用 https://www.jsonschemavalidator.net/进行验证。
任何帮助将不胜感激:)
谢谢
所以我认为这是最好忘记if
/then
/else
关键字并只定义oneOf
中的良好状态的情况之一。 (我建议oneOf
而不是anyOf
因为恰好其中一个状态应该匹配。
因此,对于您的架构,您需要
- 全部
x.value == "myVal"
y.key1 in ["a", "b"]
y.key2 in ["x", "y"]
- 全部
y.key1 in ["c", "d"]
y.key2 in ["m", "n"]
- 全部
- 不
- 其中之一
- 全部
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
属性中的值。