Issues using MinItem and uniqueItem: true to generate multiple enums - json

I am trying to create a JSON schema that validates a JSON object which can have more than 1 enum.
I have successfully created a JSON schema that is expected to validate a JSON object but the problem I am having is ensuring that the schema accepts more than one enum.
when I use the minItem : 3, three enums are generated but they are duplicates. when I add uniqueItem: true it only returns 1 enum instead of 3 unique enums.
My json schem:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$id": "https://mrlee.com/player.schema.json",
"title": "The lee schema",
"type": "object",
"properties": {
"AccountID":{
"description": "The unique identifier for a user",
"type": "integer"
},
"Permissions":{
"type": "object",
"properties":{
"granted":{
"type": "array",
"items": {
"type":"string",
"enum":[
"canLoginWithPassword",
"canVerify",
"canGame",
"canJump"
]
},
"minItems" : 4,
"uniqueItems": true
},
"failedConditions":{
"type": "array",
"items":[
{"type":"object",
"properties":{
"name":{
"type": "string"
},
"description":{
"type": "string"
},
"details":{
"type": "object",
"properties":{
"reason":{
"type": "string"
}
},
"required": [ "reason"]
},
"denied":{
"type": "array",
"items":{
"type":"string",
"enum":[
"canLoginWithPassword",
"canLoginWithPassword",
"canVerify",
"canGame",
"canJump"
]
},
"minItems":1,
"maxItems": 5
}
},
"required": [ "name", "description", "details","denied" ] }
]
}
},
"required": [ "granted", "failedConditions" ]
}
},
"required": [ "AccountID", "Permissions"]
to test that my json schema works, I use this link. would be glad if im pointed in the right direction as I am new to json and json schema

Related

JSONSchema Validation array items

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"
]
}

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"
]
}
}

"required" keyword in JSON schema

I got the below schema from http://json-schema.org/examples.html, i want to know if the required keyword can only come at the top level. or it can also come within the properties if there is a property of type object.I could not find any thing related to this in the specification https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00#section-5.4.3.
{
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 0
}
},
"required": ["firstName", "lastName"]
}
So the below example is a valid schema
{
"title":"Example Schema",
"type":"object",
"properties":{
"firstName":{
"type":"string"
},
"lastName":{
"type":"string"
},
"age":{
"type":"object",
"properties":{
"minAge":{
"type":"number"
},
"maxAge":{
"type":"number"
},
"required":[
"minAge",
"maxAge"
]
}
}
},
"required":[
"firstName",
"lastName"
]
}
4.4 Keywords with the possibility to validate container instances (arrays
or objects) only validate the instances themselves and not their
children (array items or object properties).
So I see that yes, you can have those on any level but the validation should be only consider on the same level as required
Yes, required is a valid keyword in any schema. There are no restrictions for nested schemas.
To use your example, the following is a valid schema and will validate the way you want it to.
{
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"age": {
"type": "object",
"properties": {
"minAge": {
"type": "number"
},
"maxAge": {
"type": "number"
}
},
"required": [
"minAge",
"maxAge"
]
}
},
"required": [
"firstName",
"lastName"
]
}
The required keyword can be present in any schema. This is true of all schema keywords.
(There is a special-case for the meta-keyword $schema, for which it is advisable to only have in the top level)

Is "type" optional in Json schema

{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product set",
"type": "array",
"items": {
"title": "Product",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "number"
},
"name": {
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"dimensions": {
"type": "object",
"properties": {
"length": {"type": "number"},
"width": {"type": "number"},
"height": {"type": "number"}
},
"required": ["length", "width", "height"]
},
"warehouseLocation": {
"description": "Coordinates of the warehouse with the product",
"$ref": "http://json-schema.org/geo"
}
},
"required": ["id", "name", "price"]
}
}
In the above Json schema "dimensions"is of "type": "object" , is type optional , if "type" is not specified should i assume it to be object. Could not find anything in specs related to optional elements.
https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03#section-5.1
If the property is not defined or is not in this list, then any
type of value is acceptable.
type is optional, ANY value is acceptable if type is omitted.
I think it is not optional. As you can see in the meta-schema below, the property "type" has no default value:
http://json-schema.org/schema
Also in my JSON Schema library NJsonSchema I set the type to None instead of Object. Check out the TypeRaw property:
https://github.com/rsuter/NJsonSchema/blob/master/NJsonSchema/JsonSchema4.Serialization.cs
When the default value is set to Object a lot more tests from the JSON Schema test suite fail. Maybe you can find a definite answer in this JSON Schema test suite:
https://github.com/json-schema/JSON-Schema-Test-Suite

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
}
}
}
]
}