我想表达对包含交叉键条件的架构的条件验证。使用可用的条件关键字(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"
}
}
我要表达的条件是以下两个条件
如果(x.value ==“ myVal” AND(y.key1 ==“ a” OR y.key1 ==“ b”),则 y.key2应该仅具有“ x”或“ y”
(或)
如果(y.key1 ==“ c”或y.key1 ==“ d”),则 y.key2应该仅包含“ m”或“ n”。
(要么)
y.key2可以采用y.key2属性中定义的任何允许的枚举值。
我使用JSON Schema的条件不起作用。我尝试使用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的条件为假,并为#2的条件是假的,那么任何价值已经在枚举定义y.key2
是罚款。
我们必须明确表示我们不希望#1和#2的条件的原因是,没有它们,我们只有一个true
架构,该架构允许所有内容(以前没有限制)。
现在,这里的另一个难题是您已x
在一种情况下使用过,但anyOf
子模式在的定义下y
,因此根本看不到x
。要解决此问题,您需要将该子模式作为的兄弟姐妹移动到根目录properties
。在这里,它可以查看整个实例,而不仅仅是y
属性中的值。
非常感谢。您的建议有效。。虽然我想知道为什么我不能使用if / then / else(试图减少模式的冗长性)
工作示例-jsonschema.dev/s/D3cPd