[英]Json schema validation against Json Object using javascript
我正在尝试针对 JSON 架构验证大约 100 个 JSON 对象,以查看所有字段以及类型是否符合架构。
在从站点生成的 JSON 架构下进行了尝试。 以下架构的问题是它不支持验证“文件”字段的多个项目,因为架构不完全正确。
在下面添加了架构
var schema ={
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"contents": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"version": {
"type": "string"
},
"sequence": {
"type": "integer"
},
"files": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"fileName": {
"type": "string"
},
"name": {
"type": "string"
},
"fileSize": {
"type": "string"
},
"fileType": {
"type": "string"
},
"lastUpdatedDate": {
"type": "integer"
},
"fileLength": {
"type": "integer"
},
"version": {
"type": "integer"
}
},
"required": [
"fileName",
"name",
"fileSize",
"fileType",
"lastUpdatedDate",
"fileLength",
"version"
]
}
]
}
},
"required": [
"version",
"sequence",
"files"
]
}
]
}
},
"required": [
"contents"
]
}
},
"required": [
"data"
]
}
var validator = new Validator(schema)
var json=
{
"data": {
"contents": [
{
"versionn": "2021-01-15T16:01:13.475Z",
"sequence": 1,
"files": [
{
"fileName": "us-producer-price-index.txt",
"name": "us-producer-price-index",
"fileSize": "54MB",
"fileType": "txt",
"lastUpdatedDate": 1610717473000,
"fileLength": 56614933,
"version": 2
}
]
}
]
}
};
var check = validator.check(json);
console.log(check);
if(check._error==true)
{
console.log("Error in schema")
}
虽然您的 JSON 架构是“有效的”,但它不表达任何约束。
您错过了使用properties
关键字的需要。
“属性”的值必须是 object。 这个的每一个值
object 必须是有效的 JSON 架构。如果对于出现在两个
实例并作为此关键字值中的名称,孩子
该名称的实例成功验证
对应的架构。
https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1
为了将子模式应用于 object,您需要使用properties
关键字。 像这样...
{
"required": ["data"],
"properties": {
"data": {
"type": "object"
}
}
}
此要求也适用于每个子模式。 未知关键字被忽略,因此模式根部的data
被简单地忽略,导致不表达任何约束。
您可能会发现查看 JSON 架构入门指南会有所帮助: http://json-schema.org/learn/
更新:在以答案的形式为您的问题添加更新后,看起来生成器几乎是正确的,但并不完全正确。
使用items
关键字 pre draft 2020-12 时,数组值仅将子模式项应用于相同的索引位置。 如果您希望子模式值应用于适用数组中的所有项目,则需要使用模式 object 作为值,而不是模式值数组。
“items”的值必须是有效的 JSON Schema 或数组
有效的 JSON 架构。如果“items”是一个模式,则如果数组中的所有元素都成功地针对该模式进行验证,则验证成功。
如果“items”是一个模式数组,则验证成功,如果每个
实例的元素同时针对模式进行验证
position,如果有的话。
JSON 架构草案 2019-09 - https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1
我向您推荐我们的入门指南,如上链接,其中涵盖了这一点。 如果您希望维护您的模式,那么值得一读。
我假设您想要对数组中的所有项目应用相同的验证规则。
Schema 提供列表验证和元组验证。 列表验证被指定为模式,对数组中的任何项目应用相同的规则,元组被指定为模式数组并针对schema.item[i]
验证item[i]
i]。
请注意,您的items
架构是一个元素的数组。 这意味着只有第一个元素会根据您的架构进行验证。 我假设你想要的是这个模式。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"contents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"version": {
"type": "string"
},
"sequence": {
"type": "integer"
},
"files": {
"type": "array",
"items": {
"type": "object",
"properties": {
"fileName": {
"type": "string"
},
"name": {
"type": "string"
},
"fileSize": {
"type": "string"
},
"fileType": {
"type": "string"
},
"lastUpdatedDate": {
"type": "integer"
},
"fileLength": {
"type": "integer"
},
"version": {
"type": "integer"
}
},
"required": [
"fileName",
"name",
"fileSize",
"fileType",
"lastUpdatedDate",
"fileLength",
"version"
]
}
}
},
"required": [
"version",
"sequence",
"files"
]
}
}
},
"required": [
"contents"
]
}
},
"required": [
"data"
]
}
为了说明数组验证的工作原理,我创建了一个非常有启发性的片段。
const Ajv = window.ajv7.default; const ajv = new Ajv({strict: false}); function dumpJson(item){ const el = document.createElement('pre'); el.textContent = typeof(item) === 'string'? item: JSON.stringify(item) document.body.appendChild(el); return el; } function Test(schema, title){ const validate = ajv.compile(schema) if(title)dumpJson(title).classList.add('title') dumpJson(JSON.stringify(schema, null, 2)) const tester = { with: (item) => { const el = dumpJson(item) if(validate(item)){ el.classList.add('valid'); }else{ el.classList.add('invalid'); } return tester } } return tester; } Test({ "$schema": "http://json-schema.org/draft-07/schema#", type: 'array', items: [{type: 'number'}, {type: 'string'}] }, 'tuple validation: [number]').with([0]).with([0, 1]).with([0, "a"]).with([0, "a", {}, [], null, false, true]) Test({ "$schema": "http://json-schema.org/draft-07/schema#", type: 'array', items: [{type: 'number'}] }, 'tuple validation: [number, string]').with([0]).with([0, 1]).with([0, "a"]).with([0, "a", {}, [], null, false, true]) Test({ "$schema": "http://json-schema.org/draft-07/schema#", type: 'array', items: {type: 'number'} }, 'list validation: number[]').with([0]).with([0, 1]).with([0, "a"]).with([0, "a", {}, [], null, false, true]) Test({ "$schema": "http://json-schema.org/draft-07/schema#", type: 'array', items: [{type: 'number'}, {type: 'string'}] }, 'tuple validation: [number, string]').with([0]).with([0, 1]).with([0, "a"]).with([0, "a", {}, [], null, false, true]) Test({ "$schema": "http://json-schema.org/draft-07/schema#", type: 'array', items: {'anyOf': [{type: 'number'}, {type: 'string'}]} }, 'list validation: (number|string)[]').with([0]).with([0, 1]).with([0, "a"]).with([0, "a", {}, [], null, false, true]).with(['a', 'b', 'c']).with(['a', 0]).with(['a', 0, false])
.valid { margin-left: 20px; color: green; }.invalid { margin-left: 20px; color: red; }.title { font-size: 2em; } body: { overflow: scroll; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/ajv/7.1.1/ajv7.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.