繁体   English   中英

Json 架构验证针对 Json Object 使用 ZDE9B9ED78D7E2E1DCEEFFEE780E2F9

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM