Json schema "not in" enum type? - json

I'd like to use oneOf schemas which differ only by value of xyType property. I'd like to have two of them: one where the xyType is set to "1" and the second one where xyType is any other value. Can this be done using json schemas?
"oneOf": [
{
"properties": {
"xyType": "enum": ["1"],
"whatever" : "string"
},
"type": "object"
},
{
"properties": {
"xyType": "enum": [], /// NOT "1"?
"whatever" : "string"
},
"type": "object"
}
]

There's a not operator, and the enum keyword, and you can use them together, like
{
"not": {
"enum": ["1"]
}
}

Related

Conditional statements do not apply in Json Schema

I would like to change the values acceptable to the Value B field according to the values of the Value A field in the following Json.
{"maximumList": [
{
"ValueA": 232,
"ValueB": ["aa"]
}]}
To do so, I obtained Schema using the Json Schema Generator and modified it to make it as follows.
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"maximumList": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"ValueA": {
"type": "integer"
},
"ValueB": {
"type": "array",
"items": [
{
"type": "string"
}
]
}
},
"required": [
"ValueA",
"ValueB"
],
"if":{
"properties":{
"ValueA" :{"const":232}
}
},
"then":{
"ValueB":{
"enum":["bbb"]
}
}
}
]
}
},
"required": [
"maximumList"
]
}
definitely set the value of the ValueB field to allow only "bbb", but even if "aaa" is entered in the value of the ValueB field, it passes the validation.
Is there anything I'm missing?
I think your problem is that you're using draft 4 of JSON Schema (identified by the $schema keyword value of http://json-schema.org/draft-04/schema#.
The if/then/else keywords are only supported in draft 7 and later. If you change the $schema value to http://json-schema.org/draft-07/schema#, it should work for you.

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

Is there a way to raise an error for any additional key present in JSON if I am using the if-else condition of JSON Schema?

I have a use case where I want to check the keys present in JSON, depending on the value of a different key.
Example JSON-1:
{
"key_name" : "value1",
"foo" : "random_value1"
}
Example JSON-2:
{
"key_name" : "value2",
"bar" : "random_value2"
}
As per these examples,
Rule 1. If the value of "key_name" is "value1" then only "foo" key should be present in JSON.
Rule 2. If the value of "key_name" is "value2", then only "bar" key should be present in JSON.
I have written the following JSON Schema for validating these JSON:
{
"type": "object",
"properties": {
"key_name": {
"type": "string",
"enum": [
"value1",
"value2"
]
},
"foo": {
"type": "string"
},
"bar": {
"type": "string"
}
},
"required": [
"key_name"
],
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"key_name": {
"enum": [
"value1"
]
}
}
},
"then": {
"required": [
"foo"
]
}
},
{
"if": {
"properties": {
"key_name": {
"enum": [
"value2"
]
}
}
},
"then": {
"required": [
"bar"
]
}
}
]
}
Now, as per the rules, the following JSON's are invalid, and should raise an error.
{
"key_name" : "value1",
"foo" : "random_value1",
"bar" : "random_value2"
}
OR
{
"key_name" : "value2",
"bar" : "random_value2",
"foo" : "random_value"
}
But, the above JSON Schema fails to do so.
It only checks whether "foo"/"bar" key or not, as per the value of "key_name". It fails to check for existence of any new key.
How to go about it?
This was already answered here: Mutually exclusive property groups.
Additionally, you can find a great overview here: jsonSchema attribute conditionally required.
For your specific examples, the following approaches come to mind:
Add "not": { "required": ["bar"] } to your first then clause to indicate that "bar" is not allowed. And the same for "foo" in the second then clause then.
If there is always just "key_name" and one other property allowed, you could also simply add "maxProperties": 2 in the main schema.
EDIT (to address whitelisting alternative):
Another option would be to define each permutation separately like this:
{
"oneOf": [
{
"type": "object",
"properties": {
"key_name": { "const": "value1" },
"foo": { "type": "string" }
},
"required": ["key_name", "foo"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"key_name": { "const": "value2" },
"bar": { "type": "string" }
},
"required": ["key_name", "bar"],
"additionalProperties": false
}
]
}

How to validate an enum value in a json schema validation?

the main problem resides on validate a json against a schema that deals with arrays. So, if I put a different value seems to be still valid?
json schema:
{
"transactions" : {
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"type" : {
"type" : "string",
"enum" : ["BREAK"]
},
"required":["type"]
},
"required":["items"]
}
}
}
Input JSON:
{
"transactions":[
{
"type":"BREAKDDDDDdddddddddddddddddddddddddddJDJDJDJDJDJDJDJ"
}
]
}
result: No errors found. JSON validates against the schema.
This is wrong as we haven't defined an enum type like "BREAKDDDDD"
http://www.jsonschemavalidator.net/
Any thoughts on this?
Your JSON Schema is missing certain attributes. Look at the example provided here on how to start the schema http://json-schema.org/example1.html.
Update your schema to the below and try
{
"type": "object",
"properties": {
"transactions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["BREAK"]
}
},
"required": ["type"]
}
}
}
}
To validate an enum value in a JSON schema, we can use the enum keyword. The enum keyword allows you to specify a list of allowed values for a property. For example, if you have an "enum": ["one", "two"] in your JSON schema, this will only allow the values "one", "two".
{
"type": "object",
"properties": {
"prop": {
"type": "string",
"enum": ["one", "two"]
}
}
}

A common JSON Schema for similar structure

I'm completely new to json and json schema, so I have a question (yet I don't know how much it make sense). Can we create a json schema which is common for similar type of structure. For example:
One single schema can be used to validate following json
JSON:
{
"Team_Table":
[{"Name":"New Zealand", "Match":"Six", "Won":"Six"}]
}
And
{
"Story_Taller":
[{"Story":"No Name", "Chapter":"Don't know"}]
}
Similarities:
Both have only one object in the array
Objects have string value.
Dissimilarities:
Number of properties are different
Keys are different in both
Can we do this?
Maybe this helps you along:
{
"properties": {
"Story_Taller": {
"type": "array",
"maxItems": 1,
"items": {
"properties": {
"Chapter": {
"type": "string"
},
"Story": {
"type": "string"
}
},
"additionalProperties": false
}
},
"Team_Table": {
"type": "array",
"maxItems": 1,
"items": {
"properties": {
"Name": {
"type": "string"
},
"Match": {
"type": "string"
},
"Won": {
"type": "string"
}
},
"additionalProperties": false
}
}
},
"oneOf": [
{
"title": "Story_Taller",
"required": [
"Story_Taller"
]
},
{
"title": "Team_Table",
"required": [
"Team_Table"
]
}
]
}
in (short) words:
in your JSON there must be one property of either "Story_Taller" or "Team_Table" with a maximum of 1 item
"oneOf": [ ... ]
Properties of both arrays are defined by items
"Story_Taller" must have "Chapter" and "Story" and no additional properties.
"Team_Table" must have "Name", "Match", "Won" and no additional properties.
And all of them are defined as strings.