针对包含多个模式定义的 JSON 模式进行验证
validating against a JSON schema containing multiple schema definitions
我正在创建一个 JSON 模式供 Postman 使用,其中包含一些模式定义。我根据模式验证的 JSON 需要与模式定义之一匹配。
示例架构
{
"oneOf": [
{
"$ref": "#/definitions/schema1"
},
{
"$ref": "#/definitions/schema2"
},
{
"$ref": "#/definitions/schema3"
}
],
"definitions": {
"schema1": {
"type": "object",
"properties": {
"propertyA": {
"type": "string"
}
},
"required": [
"propertyA"
]
},
"schema2": {
"type": "object",
"properties": {
"propertyB": {
"type": "string"
}
},
"required": [
"propertyB"
]
},
"schema3": {
"type": "object",
"properties": {
"propertyC": {
"type": "string"
}
},
"required": [
"propertyC"
]
}
}
}
样本JSON数据
此 JSON 根据架构进行验证并正确标记为无效(因为需要字符串):
{
"propertyA": 123
}
问题
这个例子returns 4个错误根据https://www.jsonschemavalidator.net/:
- 消息:JSON 对来自 'oneOf' 的任何模式均有效。架构路径:
#/oneOf
- 消息:类型无效。预期的字符串但得到了整数。架构路径:
#/definitions/schema1/properties/propertyA/type
- 消息:对象缺少必需的属性:propertyC。
架构路径:#/definitions/schema3/required
- 消息:对象缺少必需的属性:propertyB。
架构路径:#/definitions/schema2/required
我只对提示需要字符串的错误消息感兴趣。
如何在将架构定义保存在 1 个文件中的同时避免那些其他错误消息?
是的,oneOf
对这种事情来说太糟糕了。 if
/then
很冗长,但可以为您提供更好的结果。基本上,您需要确定一些条件来确定架构是否应应用于实例。
通常,该条件是公共字段的值。在这种情况下,如果要验证的实例是具有 "type": "A"
的对象,则它必须针对 /definitions/a
模式进行验证。如果它有 "type": "B"
那么它必须根据 /definitions/b
模式进行验证。
{
"allOf": [
{
"if": {
"properties": {
"type": { "const": "A" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/a" }
},
{
"if": {
"properties": {
"type": { "const": "B" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/b" }
}
]
}
如果您的条件是特定字段的存在,您可以使用 dependencies
关键字作为快捷方式。如果被验证的实例是一个带有“属性A”属性 的对象,那么该实例必须对 /definitions/a
模式有效。对于“属性B”也是如此。
{
"dependencies": {
"propertyA": { "$ref": "#/definitions/a" },
"propertyB": { "$ref": "#/definitions/b" }
}
}
您的示例实际上有一个超级简单的解决方案,但我回答了一般情况,因为我假设您的实际架构比示例更复杂。
{
"type": "object",
"properties": {
"propertyA": { "type": "string" },
"propertyB": { "type": "string" },
"propertyC": { "type": "string" }
},
"oneOf": [
{ "required": ["propertyA"] },
{ "required": ["propertyB"] },
{ "required": ["propertyC"] }
]
}
我正在创建一个 JSON 模式供 Postman 使用,其中包含一些模式定义。我根据模式验证的 JSON 需要与模式定义之一匹配。
示例架构
{
"oneOf": [
{
"$ref": "#/definitions/schema1"
},
{
"$ref": "#/definitions/schema2"
},
{
"$ref": "#/definitions/schema3"
}
],
"definitions": {
"schema1": {
"type": "object",
"properties": {
"propertyA": {
"type": "string"
}
},
"required": [
"propertyA"
]
},
"schema2": {
"type": "object",
"properties": {
"propertyB": {
"type": "string"
}
},
"required": [
"propertyB"
]
},
"schema3": {
"type": "object",
"properties": {
"propertyC": {
"type": "string"
}
},
"required": [
"propertyC"
]
}
}
}
样本JSON数据
此 JSON 根据架构进行验证并正确标记为无效(因为需要字符串):
{
"propertyA": 123
}
问题
这个例子returns 4个错误根据https://www.jsonschemavalidator.net/:
- 消息:JSON 对来自 'oneOf' 的任何模式均有效。架构路径: #/oneOf
- 消息:类型无效。预期的字符串但得到了整数。架构路径: #/definitions/schema1/properties/propertyA/type
- 消息:对象缺少必需的属性:propertyC。
架构路径:#/definitions/schema3/required - 消息:对象缺少必需的属性:propertyB。
架构路径:#/definitions/schema2/required
我只对提示需要字符串的错误消息感兴趣。 如何在将架构定义保存在 1 个文件中的同时避免那些其他错误消息?
是的,oneOf
对这种事情来说太糟糕了。 if
/then
很冗长,但可以为您提供更好的结果。基本上,您需要确定一些条件来确定架构是否应应用于实例。
通常,该条件是公共字段的值。在这种情况下,如果要验证的实例是具有 "type": "A"
的对象,则它必须针对 /definitions/a
模式进行验证。如果它有 "type": "B"
那么它必须根据 /definitions/b
模式进行验证。
{
"allOf": [
{
"if": {
"properties": {
"type": { "const": "A" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/a" }
},
{
"if": {
"properties": {
"type": { "const": "B" }
},
"required": ["type"]
},
"then": { "$ref": "#/definitions/b" }
}
]
}
如果您的条件是特定字段的存在,您可以使用 dependencies
关键字作为快捷方式。如果被验证的实例是一个带有“属性A”属性 的对象,那么该实例必须对 /definitions/a
模式有效。对于“属性B”也是如此。
{
"dependencies": {
"propertyA": { "$ref": "#/definitions/a" },
"propertyB": { "$ref": "#/definitions/b" }
}
}
您的示例实际上有一个超级简单的解决方案,但我回答了一般情况,因为我假设您的实际架构比示例更复杂。
{
"type": "object",
"properties": {
"propertyA": { "type": "string" },
"propertyB": { "type": "string" },
"propertyC": { "type": "string" }
},
"oneOf": [
{ "required": ["propertyA"] },
{ "required": ["propertyB"] },
{ "required": ["propertyC"] }
]
}