admin管理员组

文章数量:1336632

I have a funny scenario all over my platform, but I believe it's the best. I am trying to validate a JSON Schema where an object has unknown keys with the same schema as value. The keys are unique ID's and the value of those keys have the same schema.

To understand it, let me explain with a sample code:

let survey_questions = {
  "vv4sD32": {
    question: "Do you like dogs?",
    answers: ["Yes", "No"]
  },
  "df4sdIU": {
    question: "How about cats?",
    answers: ["Maybe", "Maybe not"]
  },
  "cbkle12": {
    question: "What do you prefer most?",
    answers: ["Dogs", "Cats"]
  }
}

As you can see, that sample is a survey, where the key is the unique ID of the question, and the value is an object with a shared schema. I know I could loop though them and check the schema on each individual question, but I have examples of nested things of these type, and would plicate things a lot. Any suggestions how to do this with AJV, or any other library?

Thank you,

Carlino

I have a funny scenario all over my platform, but I believe it's the best. I am trying to validate a JSON Schema where an object has unknown keys with the same schema as value. The keys are unique ID's and the value of those keys have the same schema.

To understand it, let me explain with a sample code:

let survey_questions = {
  "vv4sD32": {
    question: "Do you like dogs?",
    answers: ["Yes", "No"]
  },
  "df4sdIU": {
    question: "How about cats?",
    answers: ["Maybe", "Maybe not"]
  },
  "cbkle12": {
    question: "What do you prefer most?",
    answers: ["Dogs", "Cats"]
  }
}

As you can see, that sample is a survey, where the key is the unique ID of the question, and the value is an object with a shared schema. I know I could loop though them and check the schema on each individual question, but I have examples of nested things of these type, and would plicate things a lot. Any suggestions how to do this with AJV, or any other library?

Thank you,

Carlino

Share Improve this question asked Jun 26, 2019 at 9:01 Carlino GonzalezCarlino Gonzalez 3273 silver badges12 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 6

If someone will still look into this, there is patternProperties https://ajv.js/json-schema.html#patternproperties solving this pretty good

You can use additionalProperties.

For example, in your case, it could look like this:

"additionalProperties": {
    type: "object",
    properties: {
        question: { type: string }
    }
}

You can check out more details here: https://ajv.js/json-schema.html#additionalproperties

Any suggestions how to do this with AJV or any other library?

If you're open to a simple approach based on structural schemas, then please read on.

The jq mand-line program can be used to check JSON schemas.

This can be done in a variety of ways. In this response, I'll focus on the use of a schema-inference engine (which I wrote) available at https://gist.github./pkoppstein/a5abb4ebef3b0f72a6ed

This inference engine produces an easy-to-read schema in the form of a JSON document that has the same structure as the JSON entities under examination.

To illustrate, let's first assume:

  • the file named survey_questions.json holds valid JSON along the lines suggested by the "survey_questions" object in the OP.

  • the above-mentioned schema.jq file has been downloaded to the directory ~/.jq/schema/

Now invoking jq at the mand line like this:

jq 'include "schema" {"search": "~/.jq"}; [.[]] | schema
' survey_questions.json 

produces the inferred structural schema:

{
  "question": "string",
  "answers": [
    "string"
  ]
}

This can be read as follows: each question is a JSON object with at most two keys:

  • a string-valued key named "question"

  • a key named "answers", which is always an array of strings.

Notice that schema.jq makes no inferences regarding the length of arrays. To check that each "answers" array has length of at least 2 would have to be done separately.

Now suppose we added a third possible value, a number, to one of the allowed "answers".

Then the inferred schema would be:

{
  "question": "string",
  "answers": [
    "scalar"
  ]
}

Notice that answers is now inferred to be an array of scalars.

Summary

In summary, if the intended schema of a set of JSON documents or entities can be expressed in the "structural" manner supported by schema.jq, then schema checking can be acplished by paring the inferred schema with the expected schema.

Any suggestions how to do this with AJV or any other library?

You could use the JSON Extended Structural Schema language, JESS, which now es with a conformance checker (JESS.jq); it requires jq to run.

In JESS, schemas consist of one or more JSON texts. Your requirements can be specified by the following schema:

[
  "&",
  {
    "forall": ".[]",
    "schema": {
      "question": "string",
      "answer": [
        "string"
      ]
    }
  }
]

This can be read: for all values of the top-level keys, check that the value is an object matching the indicated pattern.

To determine whether your survey_questions is valid, you could (after installing JESS) use the JESS script as follows:

JESS --schema schema.json survey_questions.json

where schema.json holds the above schema, and survey_questions.json holds the JSON to be checked.

Note: I am the author of the JESS repository.

There are great answers here. At the end, I ended up creating my own library I’ve been using for years and that has bee quite popular recently. The library is https://www.npmjs./package/great-json-validator checking for the data type “array-object”. The documentation has a very google example.

本文标签: javascriptAJV schema validation for object with unknown propertiesStack Overflow