jsonschema 属性验证需要 and/or 有条件地需要
jsonschema validation of properties required and/or conditionally required
我需要验证始终具有 2 个属性的 json 对象:
- 类型
- 名字
类型可以是 "A"、"B" 或 "C"、
当类型为 "A" 时,属性 "foo" 也是必需的,不允许其他属性。
确定:
{
"type": "A",
"name": "a",
"foo": "a",
}
不正常:
{
"type": "A",
"name": "a",
"foo": "a",
"lol": "a"
}
当类型为 "B" 时,属性 "bar" 是必需的,不允许其他属性。
当类型为 "C" 时,属性 "bar" 是必需的,也可以选择 "zen" 属性。
确定:
{
"type": "C",
"name": "a",
"bar": "a",
"zen": "a"
}
{
"type": "C",
"name": "a",
"bar": "a",
}
不正常:
{
"type": "C",
"name": "a",
"bar": "a",
"lol": "a"
}
不幸的是,这个 的出色答案部分涵盖了我的情况,但是我没有设法构建适合我的 json 架构。
编辑:
这是我试过的。
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["A", "B", "C"]
},
"name": {"type": "string"},
"foo": {"type": "string"},
"bar": {"type": "string"},
"zen": {"type": "string"},
},
"anyOf": [
{
"properties": {"type": {"enum": ["A"]}},
"required": ["foo"],
},
{
"properties": {"type": {"enum": ["B"]}},
"required": ["bar"],
},
{
"properties": {"type": {"enum": ["C"]}},
"required": ["bar"],
},
]
}
我的问题是在 "anyOf" 中的对象内将字段 "additionalProperties" 设置为 false 并没有给我预期的结果。
例如以下 json 通过了验证,尽管它有额外的 属性 "lol"
{
"type": "A",
"name": "a",
"foo": "a",
"lol": "a"
}
JSON 模式是一个约束系统,其中每个子模式的约束是单独评估的。这意味着 "additionalProperties" 只能 "see" 同一直接模式对象中的 "properties" 或 "patternProperties"。
此外,它不能 "see" 基于 "required" 的属性,只能基于 "properties" 和 "patternProperties"。
据我所知,如果您在 anyOf 的 each 分支中设置 "additionalProperties": false,则 none 应该可以作为唯一允许的 属性 是 "type"。如果您这样做并且它允许 "type" 以外的属性,那么我想知道您使用的是什么实现。
以下模式适用于您的示例。希望这对其他人有帮助。诀窍是使用 additionalProperties
和 maxProperties
的组合,在正确的位置使用 required
:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
},
"name": {
"type": "string"
},
"foo": {
"type": "string"
},
"bar": {
"type": "string"
},
"zen": {
"type": "string"
}
},
"required": [
"name",
"type"
],
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "A"
}
}
},
"then": {
"required": [
"foo"
],
"maxProperties": 3
}
},
{
"if": {
"properties": {
"type": {
"const": "B"
}
}
},
"then": {
"required": [
"bar"
],
"maxProperties": 3
}
},
{
"if": {
"properties": {
"type": {
"const": "C"
}
}
},
"then": {
"required": [
"bar"
],
"maxProperties": 4
}
}
],
"additionalProperties": false
}
我需要验证始终具有 2 个属性的 json 对象:
- 类型
- 名字
类型可以是 "A"、"B" 或 "C"、
当类型为 "A" 时,属性 "foo" 也是必需的,不允许其他属性。
确定:
{
"type": "A",
"name": "a",
"foo": "a",
}
不正常:
{
"type": "A",
"name": "a",
"foo": "a",
"lol": "a"
}
当类型为 "B" 时,属性 "bar" 是必需的,不允许其他属性。
当类型为 "C" 时,属性 "bar" 是必需的,也可以选择 "zen" 属性。
确定:
{
"type": "C",
"name": "a",
"bar": "a",
"zen": "a"
}
{
"type": "C",
"name": "a",
"bar": "a",
}
不正常:
{
"type": "C",
"name": "a",
"bar": "a",
"lol": "a"
}
不幸的是,这个
编辑:
这是我试过的。
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["A", "B", "C"]
},
"name": {"type": "string"},
"foo": {"type": "string"},
"bar": {"type": "string"},
"zen": {"type": "string"},
},
"anyOf": [
{
"properties": {"type": {"enum": ["A"]}},
"required": ["foo"],
},
{
"properties": {"type": {"enum": ["B"]}},
"required": ["bar"],
},
{
"properties": {"type": {"enum": ["C"]}},
"required": ["bar"],
},
]
}
我的问题是在 "anyOf" 中的对象内将字段 "additionalProperties" 设置为 false 并没有给我预期的结果。
例如以下 json 通过了验证,尽管它有额外的 属性 "lol"
{
"type": "A",
"name": "a",
"foo": "a",
"lol": "a"
}
JSON 模式是一个约束系统,其中每个子模式的约束是单独评估的。这意味着 "additionalProperties" 只能 "see" 同一直接模式对象中的 "properties" 或 "patternProperties"。
此外,它不能 "see" 基于 "required" 的属性,只能基于 "properties" 和 "patternProperties"。
据我所知,如果您在 anyOf 的 each 分支中设置 "additionalProperties": false,则 none 应该可以作为唯一允许的 属性 是 "type"。如果您这样做并且它允许 "type" 以外的属性,那么我想知道您使用的是什么实现。
以下模式适用于您的示例。希望这对其他人有帮助。诀窍是使用 additionalProperties
和 maxProperties
的组合,在正确的位置使用 required
:
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"A",
"B",
"C"
]
},
"name": {
"type": "string"
},
"foo": {
"type": "string"
},
"bar": {
"type": "string"
},
"zen": {
"type": "string"
}
},
"required": [
"name",
"type"
],
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "A"
}
}
},
"then": {
"required": [
"foo"
],
"maxProperties": 3
}
},
{
"if": {
"properties": {
"type": {
"const": "B"
}
}
},
"then": {
"required": [
"bar"
],
"maxProperties": 3
}
},
{
"if": {
"properties": {
"type": {
"const": "C"
}
}
},
"then": {
"required": [
"bar"
],
"maxProperties": 4
}
}
],
"additionalProperties": false
}