AJV 架构验证失败

Posted

技术标签:

【中文标题】AJV 架构验证失败【英文标题】:AJV schema validation fails 【发布时间】:2018-07-30 11:42:24 【问题描述】:

我正在使用 Jsonix,我使用下面提到的命令来生成 jsonix 映射和 jsonix 架构,

java -jar jsonix-schema-compiler-full.jar -generateJsonSchema -d mappings books.xsd

它正在正确生成映射和架构,我想使用 AJV 和生成的 JSON 架构来验证 JSON,所以我已经尝试过了,

var fs = require('fs');
var Ajv = require('ajv');

var XMLSchemaJsonSchema = JSON.parse(fs.readFileSync('../node_modules/jsonix/jsonschemas/w3c/2001/XMLSchema.jsonschema').toString());
var JsonixJsonSchema = JSON.parse(fs.readFileSync('../node_modules/jsonix/jsonschemas/jsonix/Jsonix.jsonschema').toString());
var booksJsonSchema = JSON.parse(fs.readFileSync('./books.jsonschema').toString());

var ajv = new Ajv();
ajv.addSchema(XMLSchemaJsonSchema, 'http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema');
ajv.addSchema(JsonixJsonSchema, 'http://www.jsonix.org/jsonschemas/jsonix/Jsonix.jsonschema');
var validate = ajv.compile(booksJsonSchema);

var data =
   "book": [
      
         "@id": "bk001",
         "author": "Writer",
         "title": "The First Book",
         "genre": "Fiction",
         "price": "44.95",
         "pub_date":2000-10-01,
         "review": "An amazing story of nothing."
      ,
      
         "@id": "bk002",
         "author": "Poet",
         "title": "The Poet's First Poem",
         "genre": "Poem",
         "price": "24.95",
         "pub_date":2000-10-02,
         "review": "Least poetic poems."
      
   ]
;

var valid = validate(data);
if (!valid) 
    console.log('Validation failed errors:');
    console.log(validate.errors);
else
    console.log("successfully done validation");

但它正在抛出错误

/Users/qliktag/Desktop/QAGG/qagUI2/Scripts/QLIKTAG-2602/node_modules/ajv/lib/ajv.js:183
    else throw new Error(message);
               ^
Error: schema is invalid: data.definitions['nonPositiveInteger'].anyOf[0].exclusiveMaximum should be number
    at Ajv.validateSchema (/Users/qliktag/Desktop/QAGG/qagUI2/testScripts/node_modules/ajv/lib/ajv.js:185:16)
    at Ajv._addSchema (/Users/qliktag/Desktop/QAGG/qagUI2/Scripts/QLIKTAG-2602/node_modules/ajv/lib/ajv.js:316:10)
    at Ajv.addSchema (/Users/qliktag/Desktop/QAGG/qagUI2/Scripts/QLIKTAG-2602/node_modules/ajv/lib/ajv.js:136:29)
    at Object.<anonymous> (/Users/qliktag/Desktop/QAGG/qagUI2/Scripts/QLIKTAG-2602/mappings/ajvSample.js:248:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

其实错误是在ajv addschema的时候出现的,是不是我做错了什么?

【问题讨论】:

根据 JSON Scheme,exclusiveMaximum 必须是数字。但是在www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema 中,exclusiveMaximum 是假的并且ajv 正在抛出。 github.com/json-schema-org/json-schema-spec/blob/master/… 可以看到"exclusiveMaximum": "type": "number" , 【参考方案1】:

这里是 Jsonix 的作者。

正如documentation 中所指出的,JSON Schema 生成是一项实验性功能。因此,它失败也就不足为奇了。欢迎您file issues。

【讨论】:

【参考方案2】:

要继续使用 draft-04 架构,添加了 meta: false 以防止添加 draft-06 元架构 https://github.com/epoberezkin/ajv/releases/tag/5.0.0

var ajv = new Ajv(
    schemaId: 'id',
    meta: false, 
);

var metaSchema = require('../node_modules/ajv/lib/refs/json-schema-draft-04.json');
ajv.addMetaSchema(metaSchema);
ajv._opts.defaultMeta = metaSchema.id;
ajv._refs['http://json-schema.org/schema'] = 'http://json-schema.org/draft-04/schema';

添加后使用 addSchema 允许布尔值用于独占最大值

ajv.addSchema(XMLSchemaJsonSchema, 'http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema');
ajv.addSchema(JsonixJsonSchema, 'http://www.jsonix.org/jsonschemas/jsonix/Jsonix.jsonschema');

【讨论】:

【参考方案3】:

exclusiveMaximum 从布尔值变为数字发生在 JSON Schema 的 Draft-06/07 中。

// var ajv = new Ajv(schemaId: 'id');
// If you want to use both draft-04 and draft-06/07 schemas:
var ajv = new Ajv(schemaId: 'auto');
ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));

使用这个然后addSchema 允许exclusiveMaximum 的布尔值

ajv.addSchema(XMLSchemaJsonSchema, 'http://www.jsonix.org/jsonschemas/w3c/2001/XMLSchema.jsonschema');
ajv.addSchema(JsonixJsonSchema, 'http://www.jsonix.org/jsonschemas/jsonix/Jsonix.jsonschema');

【讨论】:

我已经尝试了您建议的更改,但它仍然抛出了与我上面提到的“exclusiveMaximum 应该是数字”相同的错误。我还有其他需要做的改变吗? 你有哪个版本的ajv 我使用的是ajv@6.1.1版本 ajv@6 应该支持改变模式:npmjs.com/package/ajv 终端上的另一件事是显示“schema $id ignored json-schema.org/draft-07/schema#”这到底是什么意思?

以上是关于AJV 架构验证失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 ajv 验证 json 模式时获取错误类型/值

使用 AJV 的 json 模式中的空值验证

使用 ajv 验证 UTC 日期/日期时间,但允许空字符串

如何使用 avj 和 postman 验证 json 架构

xml 和 xsd 的架构验证失败

错误:架构验证失败并出现以下错误:数据路径“”不应具有其他属性(项目)