AJV中JSON Schema的if/else/then逻辑失效问题排查
问题
用AJV做JSON Schema校验时碰上个怪事:本来要根据propertyType的值,给目标对象的键套不同的正则规则——propertyType是"123"时,键不能有空格;是其他值时,允许带空格。但测下来不管propertyType是不是"123",都只走then里的规则,else完全没生效。
原Schema片段:
"properties": { "location": { "title": "Path", "type": "string", "description": "The relative JSON path of the location to which the properties should be set", "examples": ["abc", "def"], "pattern": "^.*$" }, "properties": { "title": "Properties", "type": "object", "description": "The set of properties that shall be set on the given relative path", "if": { "properties": { "propertyType": { "const": "123" } } }, "then": { "patternProperties": { "^[-&/_.:a-zA-Z0-9]+$": { "anyOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" } ] } }, "additionalProperties": false }, "else": { "patternProperties": { "^.*$": { "anyOf": [{ "type": "string" }, { "type": "number" }, { "type": "boolean" } ] } }, "additionalProperties": false } } }
测试数据1(符合预期,校验失败):
{ "type" : "xyz", "anchor" : { "propertyType": "123" }, "setProperties" : { "random_123 " : "value1" } }
测试数据2(不符合预期,还是按then规则校验失败):
{ "type" : "xyz", "anchor" : { "propertyType": "456" }, "setProperties" : { "random_123 " : "value1" } }
问题出在哪
两个关键错误:
if规则找错地方了:原Schema里把if写在要校验的properties对象内部,它只会检查这个对象自己有没有propertyType属性,但实际propertyType在顶层的anchor对象里,和setProperties是平级的。而且原if没加required,只要对象里没propertyType,这个条件就会判定为“通过”,自然每次都走then规则。- Schema键名和测试数据对不上:Schema里要校验的对象键是
properties,但测试数据里对应的是setProperties,等于Schema没盯对目标,规则白写。
修正后的完整Schema
{ "type": "object", "properties": { "type": { "type": "string" }, "anchor": { "type": "object", "properties": { "propertyType": { "type": "string" } }, "required": ["propertyType"] }, "setProperties": { "title": "Properties", "type": "object", "description": "The set of properties that shall be set on the given relative path" } }, "required": ["anchor", "setProperties"], "if": { "properties": { "anchor": { "properties": { "propertyType": { "const": "123" } }, "required": ["propertyType"] } } }, "then": { "properties": { "setProperties": { "patternProperties": { "^[-&/_.:a-zA-Z0-9]+$": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" } ] } }, "additionalProperties": false } } }, "else": { "properties": { "setProperties": { "patternProperties": { "^.*$": { "anyOf": [ { "type": "string" }, { "type": "number" }, { "type": "boolean" } ] } }, "additionalProperties": false } } } }
修正要点
- 把
if/then/else移到顶层,这样才能读到同级的anchor.propertyType,判断逻辑才对。 - 在
if里加了required,确保anchor里必须有propertyType,避免因属性缺失导致误判。 - 把Schema里的
properties改成setProperties,和测试数据的键名对齐,让规则能作用到正确的对象上。 - 补了顶层对象的类型和必填字段,让Schema更严谨。
内容的提问来源于stack exchange,提问作者Atin Singh
相关产品推荐
相关产品推荐

