使用ajv验证带有包含换行符\n
的值的JSON文档的正确方法是什么?
简化示例:
key
的属性,该属性接受一个string
值(该模式是通过向https://jsonschema.net提交{"key":"value"}
来推断的)JSON.stringify()
对JavaScript对象进行序列化。结果,诸如\n
之类的换行符即\\n
摘要:
// JSON schema definition
const schema = {
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"required": [
"key"
],
"properties": {
"key": {
"$id": "#/properties/key",
"type": "string",
"title": "The Key Schema",
"default": "",
"examples": [
"value"
],
"pattern": "^(.*)$"
}
}
};
// a JavaScript object that has a line break
const data = { key: 'a string\nwith a line break' };
// serialize to JSON
const json = JSON.stringify(data);
// json === "{\"key\":\"a string\\nwith a line break\"}"
// validate
const Ajv = require('ajv');
const ajv = new Ajv();
const valid = ajv.validate(schema, json);
// print results
console.info('Valid:', valid);
console.info('Errors:', ajv.errors);
我希望这能奏效,但事实证明执行期间验证失败:
Valid: false
Errors: [
{
keyword: 'type',
dataPath: '',
schemaPath: '#/type',
params: { type: 'object' },
message: 'should be object'
}
]
据我了解,这是因为json
是string
,而架构定义指出它应该是object
。
我还尝试过反序列化JSON字符串,例如ajv.validate(schema, JSON.parse(json));
,但也会失败:
Valid: false
Errors: [
{
keyword: 'pattern',
dataPath: '.key',
schemaPath: '#/properties/key/pattern',
params: { pattern: '^(.*)$' },
message: 'should match pattern "^(.*)$"'
}
]
这是有道理的,因为JSON.parse()
返回了一个非JSON的JavaScript对象(例如,对于不带转义\n
字符的问题字符串值,键不加引号,而且很重要)。
依赖项:ajv 6.10.0
答案 0 :(得分:0)
我发现我使用了错误的正则表达式模式。 .
匹配除换行符以外的任何字符 。要解决此问题,我将模式更改为[\s\S]
,其中\s
字符类与“任何空白字符”匹配,而\S
字符类是其否定符,“任何非空白字符” 。此外,由于模式是在JavaScript对象的值中定义的,因此\s
和\S
中的反斜杠也必须转义,即[\\s\\S]
。因此,架构定义应如下所示:
const schema = {
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"required": [
"key"
],
"properties": {
"key": {
"$id": "#/properties/key",
"type": "string",
"title": "The Key Schema",
"default": "",
"examples": [
"value"
],
"pattern": "^([\\s\\S]*)$"
}
}
};