ajv - 验证有换行符的 JSON?

ajv - validate JSON that has line breaks?

使用 ajv 验证值包含换行符 \n 的 JSON 文档的正确方法是什么?

简化示例:

片段:

// 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() returns 不是 JSON 的 JavaScript 对象(例如,键未被引用,并且重要的是对于这个问题字符串值具有未转义的 \n个字符)。

依赖:ajv 6.10.0

原来我使用了错误的正则表达式模式。 . 匹配任何字符 除了换行符 。为了解决这个问题,我将模式更改为 [\s\S],其中 \s 字符 class 匹配 "any whitespace character" 并且 \S 字符 class 是它的否定, "any non-whitespace character"。此外,由于模式是在 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]*)$"
    }
  }
};

另见 this answer and the online regex tester