JSON Schema object contains value - json

I want to check that "obj" contains at least one value "test". But keys in the "obj" are random.
Json:
{
"title": "doc",
"obj": {
"xxxx-random": "test",
"zzzz-random": "wol"
}
}
My idea was to use oneOf but it doesn't work as I expected:
Schema Json:
{
"properties": {
"title": {
"type": "string"
},
"obj": {
"type": "object",
"oneOf": [
{
"contains": {
"properties": {
"type": "string",
"desc":"test"
}
}
}
]
}
}
}

You can do that with slightly-mindbending uses of the "not" keyword. That is, we can construct a schema that asserts:
the property "obj" must exist
"obj"'s value is an object, and there must be at least one property
and it cannot be true that all properties under "obj" do NOT match "test"
{
"type": "object",
"required": ["obj"],
"properties": {
"obj": {
"type": "object",
"minProperties": 1,
"not": {
"additionalProperties": { "not": { "const": "test" } }
}
}
}
}

Related

How Do I Require that a Sub-Property Must Exist Using JSON Schema?

In JSON Schema, I can use require to ensure that a property exists on the same level of the hierarchy, but I'm having trouble validating for nested ones.
Suppose I have following JSON Schema:
{
"type": "object",
"properties": {
"my_type": {
"type": "string"
},
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
},
"t2_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
}
}
How would I specify the following validations?
if my_type == "type1", then t1_data.id must exist
if my_type == "type2", then t2_data.id must exist
if my_type is anything else, validation passes
I've tried using the require and anyOf constructs but I could only get them to work at the same level of the hierarchy.
Thanks,
A possible solution is to combine allOf and if-then. It is a little bit verbose but I am not aware of any shorter way. Here is the schema for the case "type1":
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
"type": "object",
"properties": {
"my_type": {
"type": "string"
},
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
},
"t2_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"my_type": {
"const": "type1"
}
}
},
"then": {
"properties": {
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"required": [ "id" ]
}
}
}
}
]
}
"type2" would be quite the same as next schema in the allOf array.

Json Schema Validator Array Object property is based on enum value

I have to validate json Array object based on property enum value.
{
"college":[
{
"staffDetails": {
"etype": "hod",
"workHandling": "department"
}
},
{
"staffDetails": {
"etype": "professor",
"workHandling": "CSE"
"DataStructure": true
"Maths": false
}
}
]
}
My json schema
{
"type": "object",
"properties": {
"college": {
"type": "array",
"minItems": 2
"items":{
"$ref": "#definitions/deatils"
}
}
},
"required": ["college"],
"definition": {
"details": {
"type": "object",
"properties": {
"etype": { "enum": ["hod","professor","assistant professor"], "type":"string"},
"workHandling": {"type": "string"}
"DataStructure": {"type": "boolean"}
"Maths": {"type": "boolean"}
},
"oneOf": [
{
"properties" {
"etype": { "const": "hod"}
},
"required": ["workHandling"]
},
{
"properties" {
"etype": { "const": "professor"}
},
"required": ["workHandling", "DataStructure", "Maths"]
}
]
}
}
}
Based on "etype" inside the array object, that Array object property should marked are required.
but the schema definition is not working as expected, its expecting all ["workHandling", "DataStructure", "Maths"] in array object index 0 and 1 and so on even etype is hod.
Any suggestion, where iam missing of any other better solution...

JSON Schema - combining allOf and anyOf to make a flexible schema

In plain English, I want a flexible schema that will allow an object called "message" to contain a couple of string props, and then a 3rd prop that can be either a plain string or another object. So, if it's defined thusly, is this achieving the goal or is there a validation gotcha that I am missing?
"message": {
"type": "object",
"properties": {
"another": {
"$ref": "another.schema.json"
},
"#type": {
"type": "string",
"enum": [
"One",
"Two",
"Three"
]
}
},
"allOf": [
{
"$ref": "#message"
},
{
"anyOf": [
{
"plainolstring": {
"type": "string"
}
},
{
"obj": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
}
]
}
]
}
}
And that would validate against either
"message": {
"another": "blah",
"#type": "foo",
"plainolstring": "sdfSR345w34"
}
or
"message": {
"another": "blah",
"#type": "foo",
"obj": {
"id":"sdfSR345w34",
"type": "guid"
}
}
Validating here against Schema v7 says that it is valid, but while it may be syntactically correct, would it achieve what I want?
Yes, anyOf will do what you want - except you have a syntax error by wrapping the subschemas with those properties "plainolstring" and "obj". The correct form would be:
{
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
]
}
Moreover, you don't even need the anyOf -- you can simplify that subschema to:
{
"type": ["string", "object"],
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
The properties keyword itself does not enforce that the type must be an object -- you need to use type for that. properties just says "if this is an object, this is the definition of those properties".

Json schema not validating/working with sub schema

I have json shown below. I want to get it work against a list of zoo which will must have zoo_unique_code. But can have animal or bird or both or none of them. But i want to validate it with sub schema if it have animal or bird e.g bird/animal_id. It seems subschema is not working.
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"animal_id": {
"type": "string",
"maxLength": 24
},
"bird_id": {
"type": "string",
"maxLength": 50
},
"zoo_bird_and_animal": {
"type": "object",
"anyOf": [{
"properties": {
"zoo_bird": {
"type": "object",
"required": [
"zoo_bird_id"
],
"properties": {
"zoo_bird_id": {
"$ref": "#/definitions/bird_id"
}
}
}
}
}, {
"properties": {
"zoo_animal": {
"type": "object",
"required": [
"zoo_animal_id"
],
"properties": {
"zoo_animal_id": {
"$ref": "#/definitions/animal_id"
}
}
}
}
}
]
}
},
"properties": {
"zoo_list": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"zoo_unique_code"
],
"minProperties": 1,
"properties": {
"zoo_unique_code": {
"type": "string",
"enum": [
"NEWYORKZOO",
"PARISZOO"
]
}
},
"$ref": "#/definitions/zoo_bird_and_animal"
}
}
}
}
And testing it with
{
"zoo_list": [
{
"zoo_unique_code": "NEWYORKCODE",
"zoo_bird": {
"zoo_bird_id": "newid"
}
}
]
}
Any suggestion will be appreciated.
As far as i can interpret your schema, it seems you want to use a combining schema at the end, rather then having the ref in the same items part.
With this allOf the schema needs to be a valid object like defined in items and like the ref in the definitions
Also the other error comes from using anyOf instead of allOf.
With anyOf, it needs to be valid against either the first or the second of the schemas, as both validate against a object, even when the first is invalid, the second is valid, so everything is valid. This could also be changed with additionalProperties, but then it does not work the way you nested it.
anyOf: As long as a value validates against either of these schemas, it is considered valid against the entire combined schema.
- combining-schemas
You would also want to use allOf here, so it must validate against all, or rewrite this condition to not use an object here.
With that anyOf to allOf modification, your given data now also validates the bird_id:
And i think you are not using draft-04 here, looks like draft-7.
{
"type": "object",
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"animal_id": {
"type": "string",
"maxLength": 24
},
"bird_id": {
"type": "string",
"maxLength": 50
},
"zoo_bird_and_animal": {
"type": "object",
"allOf": [
{
"properties": {
"zoo_bird": {
"type": "object",
"required": [
"zoo_bird_id"
],
"properties": {
"zoo_bird_id": {
"$ref": "#/definitions/bird_id"
}
}
}
}
},
{
"properties": {
"zoo_animal": {
"type": "object",
"required": [
"zoo_animal_id"
],
"properties": {
"zoo_animal_id": {
"$ref": "#/definitions/animal_id"
}
}
}
}
}
]
}
},
"properties": {
"zoo_list": {
"type": "array",
"minItems": 1,
"items": {
"allOf": [
{
"type": "object",
"required": [
"zoo_unique_code"
],
"minProperties": 1,
"properties": {
"zoo_unique_code": {
"type": "string",
"enum": [
"NEWYORKZOO",
"PARISZOO"
]
}
}
},
{
"$ref": "#/definitions/zoo_bird_and_animal"
}
]
}
}
}
}
Invalid data, see: invalid:
{
"zoo_list": [
{
"zoo_unique_code": "NEWYORKCODE",
"zoo_bird": {
"zoo_bird_id": "newidnewidnewidnewidnewidnewidnewnewidnewidnewidnewidnewidnewidnew"
}
}
]
}
Valid data, see valid:
{
"zoo_list": [
{
"zoo_unique_code": "NEWYORKZOO",
"zoo_bird": {
"zoo_bird_id": "newid"
}
}
]
}

Variable object names in JSON schema

I'm attempting to define the following in JSON schema:
"codenumber": {
"12345": [
{
"prop1": "yes",
"prop2": "no"
}
]
}
The codenumber object contains a property "12345" which is always a string number that contains an array. The number value can change however, so I cannot simply define this like so:
"codenumber": {
"type": "object",
"properties": {
"12345": {
"type": "array",
"items": {
"type": "object",
"properties": {
"prop1": { "type": "string" },
"prop2": { "type": "string" }
}
}
}
}
}
Any way I can just define the first property name to be of any type of string?
You can use "patternProperties" instead of "properties":
"codenumber": {
"type": "object",
"patternProperties": {
"^[0-9]+$": {
"type": "array",
"items": {
"type": "object",
"properties": {
"prop1": { "type": "string" },
"prop2": { "type": "string" }
}
}
}
}
}