JSONSchema Validation array items - json

I receive the following items in a JSON Array
{locations: [{locId: "1", locName: "ST1"}, {locId: "2", locName: "ST2"}, {locId: "3", locName: "ST3"}]}
My requirement is that inside locations the value for locName has to be one of ST1, ST2, or ST3 (I don't care about locId). How do I enforce this in the JSONSchema. I saw you can use array but how do I specify that an object\item of the array should have one of the pre-defined values for a particular property.

You can use the enum keyword to restrict the allowed values for a given property:
"locName": {
"type": "string",
"enum": ["ST1", "ST2", "ST3"]
}
Complete schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"locations": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"locId": {
"type": "string"
},
"locName": {
"type": "string",
"enum": ["ST1", "ST2", "ST3"]
}
},
"required": [
"locId",
"locName"
]
},
]
}
},
"required": [
"locations"
]
}

Related

How do I inform a Json schema that it must have atleast one type of object in its Array, but other types are optional

I am working on updating a JSON schema for work.
For the json array, we have
"accountsInfo": [{
"type":"ADMIN",
"firstName":"Bill",
"lastName":"Cipher",
"emailAddress":"bcipher#gfalls.com"
}, {
"type":"USER"
"firstName":"Bugs",
"lastName":"Bunny",
"emailAddress":"whats#updoc.org"
}]
The USER type is needs to be optional for this schema, with the atleast 1 ADMIN type is required in the array. How can I do this?
Here is the portion of the schema file. It is using Json Schema 7.
"accountsInfo": {
"type": "array",
"uniqueItems": true,
"minItems": 2,
"items": [
{
"type": "object",
"required": [
"type",
"firstName",
"lastName",
"emailAddress"
],
"properties": {
"type": {
"type": "string",
"enum": [
"ADMIN",
"USER"
]
},
"firstName": {
"type": "string",
"$ref": "#/definitions/non-empty-string"
},
"lastName": {
"type": "string",
"$ref": "#/definitions/non-empty-string"
},
"emailAddress": {
"type": "string",
"format": "email"
}
}
}
]
}
You can use the "contains" keyword for this. In pseudocode: "the array must contain (at least one) item that successfully evaluates against this schema".
As a sibling keyword to "type": "object" and "items": { ... }, add:
"contains": {
"properties": {
"type": {
"const": "ADMIN"
}
}
}
Also, you have an error in your "items" keyword: if you intend for that subschema to match all items, not just the first, remove the extra array around the schema. The array form of "items" matches each item in the data against each item in the schema in turn, and you only specify a schema for the first item, so all items after the first can be anything.
"items": { .. schema .. } not "items": [ { .. schema .. } ].
If using the contains keyword as suggested, and if you are using strict mode, you may need to add "type": "array" like this:
{
"type": "array",
"contains": {
"properties": {
"type": {
"const": "ADMIN"
}
}
}
}

JsonSchema - Only allow one item in an array field if another array field is defined

I have the following json and would like to only allow "leads" to contain only a single "id" item if there is a "tokens" array present (with at least one item).
JSON
{
"input": {
"leads": [
{
"id": 795333333760
}
],
"tokens": [
{
"name": "tem_x",
"value": "Renew_all"
},
{
"duration": "90",
"eligibility": "eligible"
}
]
}
I have the following schema, that indicates "tokens" can have more than one item if present and that "leads" is required.
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"leads": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"id": {
"type": "integer"
}
},
"required": [
"id"
]
}
]
},
"tokens": {
"type": "array",
"minItems": 1
}
},
"required": [
"leads",
]
}
},
"required": [
"input"
]
}
Is there a way to ensure that only one item in "leads" can be allowed if "tokens" is present (as it is not defined as a required field). If "tokens" is not defined, then I would like to allow the "leads" array to have more than one item.
I played around with if-then but wasn't able to get it working right. Any help is appreciated.
Thank you.
This is the kind of thing the dependencies keyword is for. It can be done with if/then or implication as well, but dependencies removes all the extra boilerplate needed for those patterns. The following says, if the "tokens" property is defined, then the "leads" property must have at most 1 item. This would go inside your "input" schema.
"dependencies": {
"tokens": {
"properties": {
"leads": { "maxItems": 1 }
}
}
}
Edit: dependencies works in draft-04 thru draft-07. In draft 2019-09 and up, you can use dependentSchemas instead.
try to use like this:
{
"properties": {
"tokens": {},
"leads": {}
},
"anyOf": [{
"required" : ["tokens"]
}, {
"required" : ["leads"]
}]
}
so schema looks like this:
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"leads": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"id": {
"type": "integer"
}
},
"required": [
"id"
]
}
]
},
"tokens": {
"type": "array",
"minItems": 1
}
},
"anyOf": [{
"required" : ["tokens"]
}, {
"required" : ["leads"]
}]
}
},
"required": [
"input"
]
}

JSON Schema for child objects with different set of keys

I have JSON data of which is an array of data like
[
{
"type": "background_color",
"data": {
"backgroundColor": "F9192D"
}
},
{
"type": "banner_images",
"data": {
"images": [
{
"url": "https://example.com/abc.jpg",
"id": 3085
},
{
"url": "https://example.com/zyx.jpg",
"id": 3086
}
]
}
},
{
"type": "description_box",
"data": {
"text": "Hello 56787"
}
}
]
The data is an array of object which has two keys type and data. The type and keys of the data will be defined by the type of data it has.
Like for background_color type, the data should have backgroundColor property, while for banner_images, data should have images which is an array of other properties.
Till now, What I have done is
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"title": "category schema",
"description": "Used to validate data of category",
"examples": [],
"required": [],
"items": {
"type": "object",
"required": [
"type",
"data"
],
"properties": {
"type": {
"type": "string",
"enum": ["background_color", "banner_images", "description_box"]
},
"data": {
"type": "object" // How to define data property here for each use case
}
}
}
}
I'm not getting how to define the data property for each use case?
You can use if/then/else blocks to define conditional constraints.
The values of if and then are schemas. If the if schema is valid, then the then schema is applied, otherwise, the allOf subschema (allOf[0] in this example) would pass validation.
There are a few different ways to do this, but this is clean when you don't have any additional or special requirements. Please come back if you do =]
In this example, I've added banner_images...
You can test it working here.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"title": "category schema",
"description": "Used to validate data of category",
"items": {
"type": "object",
"required": [
"type",
"data"
],
"properties": {
"type": {
"type": "string",
"enum": [
"background_color",
"banner_images",
"description_box"
]
},
"data": {
"type": "object"
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "banner_images"
}
}
},
"then": {
"properties": {
"data": {
"required": [
"images"
],
"properties": {
"images": {
"type": "array"
}
}
}
}
}
}
]
}
}
For reference, here's the part of the JSON Schema draft-7 spec document that details the behaviour: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.6

JSON Schema reporting error only for first element of array

I have the below JSON document.
[
{
"name": "aaaa",
"data": {
"key": "id",
"value": "aaaa"
}
},
{
"name": "bbbb",
"data": {
"key": "id1",
"value": "bbbb"
}
}
]
Below is the JSON Schema I have created for the above content.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"key": {
"type": "string",
"enum": [
"id",
"temp",
]
},
"value": {
"type": "string",
}
},
"required": [
"key",
"value"
]
}
},
"required": [
"name",
"data"
]
}
]
}
As per the schema, the value of data.key is invalid for second item in the array. but any online schema validator does not find that. If we use different value in first array element, it throws the excepted error.
I assume that my schema is wrong somehow. what I expect is that any child items of the array should be reported if they have values out of the enum list.
It's an easy mistake to make, so don't beat yourself up about this one!
items can be an array or an object. If it's an array, it validates the object at that position in the instance array. Here's an excerpt from the JSON Schema spec (draft-7)
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 (validation) draft-7 items
Removing the square braces provides you with the correct schema...
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items":
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"data": {
"type": "object",
"properties": {
"key": {
"type": "string",
"enum": [
"id",
"temp",
]
},
"value": {
"type": "string",
}
},
"required": [
"key",
"value"
]
}
},
"required": [
"name",
"data"
]
}
}

How to define JSON schema for object that holds Properties object?

I need to create a JSON schema for object that will include java Properties object as one of its properties.
The nested Properties object will be simply list of key=value. Both key and value are of type string.
I failed to find any docs that describe how to define the schema that includes 2 new types.
shall it be something like:
{
"type": "object",
"name": "MyObj",
"properties": {
"prop1": {
"type": "string",
"description": "prop1",
"required": true
},
"props": {
"type": "array",
"items": {
"type": "object"
"properties": {
"key": {
"type": "string",
"description": "key",
"required": true
},
"value": {
"type": "string",
"description": "the value",
"required": true
}
}
"description": "the value",
"required": true
}
}
}
}
The schema you have written (assuming the commas are fixed) describes data of the form:
{
"prop1": "Some string property goes here",
"props": [
{"key": "foo", "value": "bar"},
{"key": "foo2", "value": "bar2"},
...
]
}
If this is what you wanted, then you are already finished.
However, I do wonder why you are using key/value pairs in an array, when you could use a JSON object with string keys instead. Using the additionalProperties keyword, you could have a schema:
{
"type": "object",
"name": "MyObj",
"properties": {
"prop1": {
"type": "string",
"description": "prop1"
},
"props": {
"type": "object",
"additionalProperties": {
"type": "string",
"description": "string values"
}
}
}
}
This describes a data format like:
{
"prop1": "Some string property goes here",
"props": {
"foo": "bar",
"foo2": "bar2"
}
}
At W3 schools (JSON Syntax) you can read how the array should be defined.
There is no schema like the xsd for xml, however i've found an approach on json-schema.org. If you are able to, i'll advice to youse google-GSON library for JSON. You could Store key Value as "id" : "value" and build only one object, containing all requieed pairs:
{ "lang" : "EN" , "color" : "red" }
Your posted model is incorect, you can check it on jsonlint.com
Here is a working version, i'm not sure if the modell is as expected.
{
"type": "object",
"name": "MyObj",
"properties": [
{
"prop1": {
"type": "string",
"description": "prop1",
"required": true
},
"props": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "key",
"required": true
},
"value": {
"type": "string",
"description": "the value",
"required": true
}
},
"description": "the value",
"required": true
}
}
}
]
}