使用javascript对Json对象进行Json模式验证



我试图对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

我建议您参考我们的入门指南,如上面的链接,它涵盖了这一点。如果您希望维护您的模式,那么值得一读。

相关内容

  • 没有找到相关文章

最新更新