Validating an object's schema using AJV when there are unknown properties present

Within my platform, there is an amusing scenario that I find to be the most effective. I am currently attempting to validate a JSON Schema where an object contains unknown keys with a consistent schema as their values. Each key represents a unique ID and holds data structured in the same way.

To illustrate this concept, consider the following 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"]
  }
}

In this example, the data represents a survey where each unique key corresponds to a question ID and its value conforms to a specific schema. While I could individually check each question's schema by looping through them, I have encountered nested scenarios of similar structure which could complicate the process. Do you have any suggestions on how to achieve this validation using AJV or another library?

Thank you,

Carlino

Answer №1

For anyone interested in further exploration, there exists a helpful solution utilizing patternProperties. More information can be found at

Answer №2

If you want to allow for extra properties in your JSON schema, you can leverage the additionalProperties field.

A practical example tailored to your scenario would involve defining it like so:

"additionalProperties": {
    type: "object",
    properties: {
        query: { data type: string }
    }
}

To delve deeper into this concept, feel free to refer to this resource:

Answer №3

Is there a way to achieve this using AJV or any other library?

If you're interested in taking a straightforward approach based on structural schemas, then keep reading.

The command-line tool called jq can be utilized for validating JSON schemas.

There are multiple ways to accomplish this task. In this response, I will focus on utilizing a schema-inference engine (which I developed) that is accessible at https://gist.github.com/pkoppstein/a5abb4ebef3b0f72a6ed

This inference engine generates a user-friendly schema presented as a JSON document with the same structure as the JSON entities being examined.

For example, let's assume:

  • the valid JSON is stored in a file named survey_questions.json similar to the "survey_questions" object mentioned in the original post.

  • the schema.jq file has been downloaded and saved in the directory ~/.jq/schema/

To execute jq from the command line, use the following command:

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

This will output the inferred structural schema:

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

In essence, each question is considered a JSON object containing keys like "question" which is a string and "answers", an array of strings.

Note that the schema generated does not specify the length of arrays. Verifying that each "answers" array has a minimum length of 2 would need to be performed separately.

If we introduce a third possible value (such as a number) to the "answers" array, the updated inferred schema would look like:

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

Here, it indicates that the "answers" array now consists of scalars.

Summary

To summarize, if the desired schema for a collection of JSON documents or entities can be expressed using the "structural" format supported by schema.jq, schema validation can be achieved by comparing the inferred schema with the expected one.

Answer №4

Do you have any ideas on how to accomplish this using AJV or another library?

One option is to utilize the JSON Extended Structural Schema language, known as JESS. This language now includes a conformance checker called JESS.jq, which requires the use of jq to function properly.

Within JESS, schemas are comprised of one or more JSON texts. Your specific criteria can be defined with the following schema:

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

This schema essentially states that for all top-level keys, validate that the value is an object that matches the specified pattern.

To verify the validity of your survey_questions data, you can run the JESS script after installing it:

JESS --schema schema.json survey_questions.json

Ensure that the schema.json file contains the above schema definition and that survey_questions.json contains the JSON data to be checked.

It's worth noting that the author of the JESS repository is providing this information.

Answer №5

I discovered some incredible solutions in this thread. Eventually, I decided to develop my own library that I've been utilizing for several years now and has recently gained popularity. This library, which can be found at https://www.npmjs.com/package/great-json-validator, specializes in validating the data type "array-object". The documentation includes a very thorough example.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

``I'm having trouble getting the onchange event to function properly in a customized

After following a tutorial, I successfully created a custom select dropdown using the provided link. https://www.w3schools.com/howto/tryit.asp?filename=tryhow_custom_select However, I am facing an issue with the onchange event not working for the select ...

The creation of an indexedDB database and the addition of content encountered an error while trying to perform a 'transaction' on the IDBDatabase

I am relatively new to using IndexedDB and have successfully created a database. However, I am encountering an error when trying to add content to it. The specific error message reads: Uncaught NotFoundError: Failed to execute 'transaction' on ...

Creating a global variable in Angular that can be accessed by multiple components is a useful technique

Is there a way to create a global boolean variable that can be used across multiple components without using a service? I also need to ensure that any changes made to the variable in one component are reflected in all other components. How can this be ac ...

Modify appearance of text depending on input (HTML & JS)

I am currently working on building an HTML table using Django. My goal is to dynamically change the color of numbers in the table to red when they are negative and green when they are positive. I understand that JavaScript is required for this functionalit ...

Adding elements to an array appears to cause the previously created object to react

I am encountering a situation where once I add an object to an array, it becomes reactive to any changes made. // actions.js export const addToCart = ({ commit }) => { commit('addToCart'); // successfully updates the state setTimeout ...

How about a demonstration of Angular and Ionic working together in a chat

I am attempting to replicate a similar example found in the default Ionic template (tabs). This example features a tab labeled chat containing multiple images with descriptions. When an item in the list is clicked, more detailed information is displayed. T ...

How can I assign a unique background color to each individual column within a RadioButtonList?

I have an issue with setting 3 repeated columns. I want to assign different background colors to each of them. If you have any ideas on how I can achieve this, please share. Here is the code for my RadioButtonList: <asp:RadioButtonList ID="rblTimeSlot ...

Having trouble loading a model converted from FBX to JSON using THREE.JSONLoader

I recently converted an FBX model to JSON using a Python script called convert-to-threejs.py. However, I am encountering issues trying to load it into three.js (r58). An error message stating "Uncaught TypeError: Cannot read property 'length' of ...

In swift 3.0, the tableview is unable to display data obtained from a web API in JSON format

Recently, I delved into IOS development using swift 3.0 and created a basic app to fetch data from a server database via a web API. The JSON data was successfully retrieved and parsed into a string array. However, despite being able to print the array, I f ...

"Utilizing Node.js and Express to return JSONP data based on

For some reason, my Express application is giving me a strange result when using res.jsonp. It looks like this: /**/ typeof jsonp1406719695757 === 'function' && jsonp1406719695757({"published":true,"can_add_to_cart":true,"updated_at":"20 ...

Despite a valid entry from a list, the controller is receiving null values in MVC 4 with AJAX integration

I am currently developing a "create" form that includes fields for OriginAirportID and DestinationAirportID. Currently, when a user inputs a string of letters into these fields, an AJAX request is triggered to retrieve data in JSON format. This data is th ...

Create a JavaScript array containing all the elements from a MySQL table

I am attempting to store my mysql table data in a JavaScript array. My goal is to push each element of the table into the array so that it looks like this: array[0] = [question: information01, answer: information02...] array[1] = [question: information11, ...

Is it advisable to utilize jQuery's parseJSON/getJSON functions?

Upon examining the jQuery parseJSON function, I discovered that it essentially performs a basic regex validation: parseJSON: function( data ) { if ( typeof data !== "string" || !data ) { return null; } // Remove leading/trailing white ...

How to give focus to a div in IE 8 after pressing the tab key, no jQuery required

We are facing a challenge with our datagrid where we have implemented navigation using the tab key. In IE 7 & 8, pressing the tab key shifts the focus away from the grid to the next element on the page. While in other browsers, we were able to prevent thi ...

accurate JSONP reply

Currently, I am experimenting with JSONP locally to receive a correct response and pass it into my callback function jsonp_callback. I am referencing code from: How do I set up JSONP? header('content-type: application/json; charset=utf-8'); $dat ...

Looking to deactivate a particular checkbox in a chosen mode while expanding the tree branches

I encountered an issue with a checkbox tree view where I needed to disable the first two checkboxes in selected mode. While I was able to achieve this using the checked and readonly properties, I found that I could still uncheck the checkboxes, which is no ...

Display sibling element upon hovering with AngularJS

Within a single view, I have multiple instances of repeated content elements. Each content element contains an anchor element. My goal is to toggle a class on a sibling element within that specific content element when a user hovers over the anchor. For c ...

When using Javascript, you can expect to receive a modified structure that is different from

I am dealing with an array of objects that have the following structure: const data: [ { id: 21786162, label: "cBTC 2021-06-25 Put $50,000.00", active": true, type: "put", strike_price: 5000000, date_live: "2019-11- ...

Nuxt.js ERROR: Unable to find reference to 'window' object

Currently working with Nuxt.js and encountering an issue while configuring vuex-persist. Seeking assistance from someone familiar with this problem. store/index.js store/LangModule.js ...

Is there a way to programmatically update the content of a React Bootstrap modal?

I have been attempting to modify the content of a modal after it has been loaded, but I am struggling to identify the correct nodes for modification. I have added references to the nodes I want to change and attempted to alter them in componentDidMount(). ...