admin管理员组

文章数量:1432205

I am trying to validate around 100 JSON Objects against a JSON schema to see if all the fields along with the type are as per the schema or not.

Tried below JSON schema which was generated from a site. The issue with the below schema is that it does not support validation of multiple items for the "files" field as the schema is not pletely correct.

Added below schema

     var schema ={
  "$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")
  }

I am trying to validate around 100 JSON Objects against a JSON schema to see if all the fields along with the type are as per the schema or not.

Tried below JSON schema which was generated from a site. The issue with the below schema is that it does not support validation of multiple items for the "files" field as the schema is not pletely correct.

Added below schema

     var schema ={
  "$schema": "http://json-schema/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")
  }
Share Improve this question edited Feb 23, 2021 at 17:02 Suraj Prasad asked Feb 19, 2021 at 5:59 Suraj PrasadSuraj Prasad 2514 silver badges28 bronze badges 4
  • Your JSON is invalid. – Richard Rublev Commented Feb 19, 2021 at 6:03
  • @RichardRublev the schema is invalid? Could you please suggest the change – Suraj Prasad Commented Feb 19, 2021 at 6:13
  • Check with jsonformatter.curiousconcept./# – Richard Rublev Commented Feb 19, 2021 at 6:22
  • @RichardRublev added valid schema , still same output – Suraj Prasad Commented Feb 19, 2021 at 6:44
Add a ment  | 

2 Answers 2

Reset to default 3

I assume that what you want is to apply the same validation rule for all the items in your array.

Schema provides list validation and tuple validation. The list validation is specified as a schema, apply the same rule for any item in the array, the tuple is specified as an array of schemas and validate item[i] against schema.item[i].

Notice that your items schemas is an array of one element. This means that only the first element is validated against your schema. What I assume you want instead is this schema.

{
  "$schema": "http://json-schema/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"
  ]
}

Additional examples

In order to illustrate the how the array validation works I created a snipped that is very enlightening.

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.pile(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/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/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/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/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/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./ajax/libs/ajv/7.1.1/ajv7.min.js"></script>

While your JSON Schema is "valid", it doesn't express any constraints.

you have missed the need to use the properties keyword.

The value of "properties" MUST be an object. Each value of this
object MUST be a valid JSON Schema.

Validation succeeds if, for each name that appears in both the
instance and as a name within this keyword's value, the child
instance for that name successfully validates against the
corresponding schema.

https://datatracker.ietf/doc/html/draft-handrews-json-schema-02#section-9.3.2.1

In order to apply a subschema to an object, you need to use the properties keyword. Like this...

{
  "required": ["data"],
  "properties": {
    "data": {
      "type": "object"
    }
  }
}

This requirement applies for each subschema too. Unknown keywords are ignored, so data at the root of the schema was simply ignored, resulting in no constraints being expressed.

You may find it helpful to review the JSON Schema getting started guide: http://json-schema/learn/


Update: After adding an update to your question in the form of an answer, it looks like the generator is almost right, but not quite.

When using the items keyword pre draft 2020-12, array values apply subschemas items to the same index location only. If you want the subschema value to apply to all items in the applicable array, you need to use a schema object as the value as opposed to an array of schema values.

The value of "items" MUST be either a valid JSON Schema or an array
of valid JSON Schemas.

If "items" is a schema, validation succeeds if all elements in the array successfully validate against that schema.

If "items" is an array of schemas, validation succeeds if each
element of the instance validates against the schema at the same
position, if any.

JSON Schema draft 2019-09 - https://datatracker.ietf/doc/html/draft-handrews-json-schema-02#section-9.3.1.1

I refer you to our getting started guide, as linked above, which covers this. If you expect to maintain your schemas, it would be worth reading.

本文标签: nodejsJson schema validation against Json Object using javascriptStack Overflow