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个条件
If (x.value == "myVal" AND (y.key1 == "a" OR y.key1 == "b ") then y.key2 应该只有 "x" 或 "y"
(或)
If ( y.key1 == "c" OR y.key1 == "d") 然后 y.key2 应仅包含“m”或“n”。
(或)
y.key2 可以采用 y.key2 属性.
中定义的任何允许的枚举值
我使用 JSON 架构的条件不起作用。我尝试使用 https://www.jsonschemavalidator.net/ 进行验证。
任何帮助将不胜感激:)
谢谢
所以我认为这是最好忘记 if
/then
/else
关键字并只在 [=13 中定义好的状态的情况之一=]. (我建议 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
(或者 {}
如果你是 pre-draft-6)
看来您已经解决了#1 和#2;只需删除条件逻辑。起作用的是#3 中的 NOT。这里我们说的是,如果#1 的条件为假 并且 的条件为假,#2 的条件为假,那么枚举中已经为 y.key2
定义的任何值都可以。
我们必须明确表示我们不想要 #1 和 #2 的条件的原因是没有它们,我们只有一个 true
模式,它允许一切(以前没有约束).
现在这里的另一个陷阱是你在你的一个条件中使用了 x
,但是你的 anyOf
子模式在 y
的定义之下,所以它不能'根本看不到 x
。要解决此问题,您需要将该子模式移动到根目录,作为 properties
的同级。在这里它可以查看整个实例,而不仅仅是 y
属性.
中的值
我想表达包含交叉键条件的模式的条件验证。在 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个条件
If (x.value == "myVal" AND (y.key1 == "a" OR y.key1 == "b ") then y.key2 应该只有 "x" 或 "y"
(或)If ( y.key1 == "c" OR y.key1 == "d") 然后 y.key2 应仅包含“m”或“n”。
(或)
y.key2 可以采用 y.key2 属性.
中定义的任何允许的枚举值
我使用 JSON 架构的条件不起作用。我尝试使用 https://www.jsonschemavalidator.net/ 进行验证。
任何帮助将不胜感激:)
谢谢
所以我认为这是最好忘记 if
/then
/else
关键字并只在 [=13 中定义好的状态的情况之一=]. (我建议 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
(或者{}
如果你是 pre-draft-6)
- 没有
看来您已经解决了#1 和#2;只需删除条件逻辑。起作用的是#3 中的 NOT。这里我们说的是,如果#1 的条件为假 并且 的条件为假,#2 的条件为假,那么枚举中已经为 y.key2
定义的任何值都可以。
我们必须明确表示我们不想要 #1 和 #2 的条件的原因是没有它们,我们只有一个 true
模式,它允许一切(以前没有约束).
现在这里的另一个陷阱是你在你的一个条件中使用了 x
,但是你的 anyOf
子模式在 y
的定义之下,所以它不能'根本看不到 x
。要解决此问题,您需要将该子模式移动到根目录,作为 properties
的同级。在这里它可以查看整个实例,而不仅仅是 y
属性.