我试图对JSON模式验证大约100个JSON对象,以查看所有字段以及类型是否与模式一致。
在从站点生成的JSON模式下尝试。下面模式的问题是,它不支持对"文件"的多个项进行验证。字段作为模式不完全正确
在schema
下面添加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")
}
我假设您希望对数组中的所有项应用相同的验证规则。
Schema提供列表验证和元组验证。验证被指定为模式,对数组元组中的任何项应用相同的规则。被指定为模式数组并验证item[i]
与schema.item[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>
虽然JSON Schema是" valid",但它不表示任何约束。
您错过了使用properties
关键字的需要。
属性"必须是一个对象。
如果
对象的每个值必须是一个有效的JSON Schema。
实例中出现的每个名称以及作为该关键字值中的名称,该名称的子
实例根据对应的模式成功验证,则验证成功。
https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02 section-9.3.2.1
为了将子模式应用于对象,需要使用properties
关键字。像这样…
{
"required": ["data"],
"properties": {
"data": {
"type": "object"
}
}
}
此要求也适用于每个子模式。未知关键字被忽略,所以模式根的data
被忽略,导致没有约束被表达。
您可能会发现查看JSON Schema入门指南很有帮助:http://json-schema.org/learn/
更新:在以答案的形式向您的问题添加更新后,看起来生成器几乎是正确的,但并不完全正确。
当使用items
关键字pre draft 2020-12时,数组值仅将子模式项应用于相同的索引位置。如果希望子模式值应用于适用数组中的所有项,则需要使用模式对象作为值,而不是使用模式值数组。
item "必须是一个有效的JSON Schema或者一个有效的JSON Schema数组
如果"items"中的所有元素验证成功
如果"items"是一个模式数组,如果实例的每个
元素在相同的
位置(如果有的话)对模式进行验证,则验证成功。
JSON Schema draft 2019-09 - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02#section-9.3.1.1
我建议您参考我们的入门指南,如上面的链接,它涵盖了这一点。如果您希望维护您的模式,那么值得一读。