我试图找到一种方法来改变模式验证,以便为给定对象找到最合适的模式。我们假设我们有一个架构:
{
"oneOf": [
{
"$ref": "#/definitions/a"
},
{
"$ref": "#/definitions/b"
}
],
"definitions": {
"a": {
"type": "object",
"properties": {
"prop1": {
"enum": ["x"]
}
},
"required": ["prop1"]
},
"b": {
"type": "object",
"properties": {
"prop1": {
"enum": ["y"]
},
"prop2": {
"type": "string"
}
},
"required": ["prop1", "prop2"]
}
}
}
现在,如果我有一个对象{ "prop1": "y" }
,我希望它从#/definitions/b
类型解析,即使它对此方案不是真的有效。也就是说,我想只使用prop1
属性来解析。
我想知道是否有办法使用AJV自定义关键字,而无需重建架构本身?特别是,如果schema对某个对象无效,是否可以使用自定义关键字覆盖它并使其有效?
答案 0 :(得分:1)
如果目标是仅报告来自正确架构的错误,您可以使用"switch"(使用v5选项,从版本5.0.0移至ajv-keywords)或"if/then/else" (建议因为它可能会在JSON Schema草案7中添加):
{
"id": "schema",
"if": { "properties": { "prop1": { "const": "x" } } },
"then": { "$ref": "#/definitions/a" },
"else": { "$ref": "#/definitions/b" }
}
如果您需要知道哪个架构用于验证,您可以使用自定义关键字来记录它:
{
"id": "schema",
"if": { "properties": { "prop1": { "const": "x" } } },
"then": {
"allOf": [
{ "schemaUsed": "schema#/definitions/a" },
{ "$ref": "#/definitions/a" }
]
},
"else": {
"allOf": [
{ "schemaUsed": "schema#/definitions/b" },
{ "$ref": "#/definitions/b" }
]
}
}
应该定义关键字以在验证期间在某个变量中存储模式ID,以便在验证之后您可以看到使用了哪个。
如果您需要获得实际架构,您可以这样做:
var validate = ajv.getSchema('schema#/definitions/a'); // validating function
var schema = validate.schema; // schema as JSON