Maybe sounds confusing, I want to validate this model schema (should has $schema, title, properties and required field):
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "My Schema",
"type": "object",
"properties": {
"myData": {
"type": "object",
"properties": {
"name_1": {
"type": "string"
},
"name_2": {
"type": "string"
},
"name_3": {
"type": "string"
}
}
}
},
"required": [
"myData"
]
}
I've already done this:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"$schema": {
"type": "string"
},
"title": {
"type": "string"
},
"properties": {
"type": "object",
"enum": "myData"
},
"required": {
"type": "array",
"items": {
"myData": "string"
}
}
}
}
but this part is not working well:
"properties": {
"type": "object",
"enum": "myData"
},
Is possible to do this? or is prohibited to use those built schema words like: "required", "enum", "properties" as a property inside "properties"?.
Thanks in advance for helping me to understand this part :)
My fault, sorry. I've created wrong the json schema, it should be like this:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "http://jsonschema.net",
"type": "object",
"properties": {
"title": {
"type": "string"
},
"type": {
"type": "string"
},
"properties": {
"type": "object",
"properties": {
"myData": {
"type": "object"
}
}
},
"required": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
And works fine :)
Related
I have created a JSON schema to validate a simple JSON file. The good news is that it validates in the way that I intended, in that any number of booking elements can appear in any order, and no extra properties are allowed in each type of booking element.
Ideally I would like to remove the full list of possible properties in a bookingElement object (id, type, depair, destair, city) in the JSON schema, and just leave the oneOf lists, which show clearly which fields are allowed in each different type of element.
Can anyone provide a version of the schema without that full list that still applies the strict rules?
This is the JSON:
{
"bookingElements": [
{
"id" : "00003",
"type" : "flight",
"depair" : "LHR",
"destair" : "CDG"
},
{
"id" : "00008",
"type" : "hotel",
"city" : "Paris"
}
]
}
The schema is:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"bookingElements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"depair": {
"type": "string"
},
"destair": {
"type": "string"
},
"city": {
"type": "string"
}
},
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"depair": {
"type": "string"
},
"destair": {
"type": "string"
}
}
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"city": {
"type": "string"
}
}
}
]
}
}
},
"required": [
"bookingElements"
]
}
Ideally the JSON schema would look something closer to the following:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"bookingElements": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"depair": {
"type": "string"
},
"destair": {
"type": "string"
}
}
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string"
},
"city": {
"type": "string"
}
}
}
]
}
}
},
"required": [
"bookingElements"
]
}
I'm building a json schema definition which has a fixed set of controls that I've currently limited with an enum. However, not all properties are relevant for all controls.
I only want to require an options property if the controlType = dropdown
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"controlType": {
"type": "string",
"enum": ["title", "dropdown", "button"]
},
"options:": {
"type": "array",
"items": {"type": "string"}
}
}
}
}
How can I conditionally include / require a field in a json schema?
Use IF..Then..Else new in Draft-07
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"controlType": {
"type": "string",
"enum": ["title", "dropdown", "button"]
},
"options:": {
"type": "array",
"items": {"type": "string"}
}
},
"if": {
"properties": {
"controlType": {"const": "dropdown"}
}
},
"then": {
"required": ["options"]
}
}
}
Use oneOf or anyOf
This can be useful if you have a property that has a limited number of acceptable values (such as an enum), but each possible value needs to be individually mapped.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"controlType": {
"type": "string",
"enum": ["title", "dropdown", "button"]
},
"options:": {
"type": "array",
"items": {"type": "string"}
}
},
"anyOf": [
{
"properties": {
"controlType": {"const": "dropdown"}
},
"required": ["controlType", "options"]
},
{
"properties": {
"controlType": {"const": "title"}
},
"required": ["controlType"]
},
{
"properties": {
"controlType": {"const": "button"}
},
"required": ["controlType"]
}
]
}
}
Further Reading
Conditionally require attribute
Applying subschemas conditionally
Combining schemas
I have the input json like below,
{"contents":[{"type":"field"},{"type":"field","itemId":"594b9980e52b5b0768afc4e8"}]}
the condition is,
if the type is 'field', then 'itemId' should be the required field
and if the type is 'fieldGroup' or 'subSection', then 'itemId' is optional
This is the Json Schema I tried and its not working as expected,
"type": "object",
"additionalProperties": false,
"properties" : {
"contents" : {
"type" : "array",
"items": {"$ref": "#displayItem" }
}
},
"definitions": {
"displayItem" : {
"id": "#displayItem",
"type": "object",
"items": {
"anyOf": [
{"$ref": "#fieldType"},
{"$ref": "#fieldGroupSubSectionType"}
]
}
},
"fieldType" : {
"id": "#fieldType",
"type": "object",
"additionalProperties": false,
"properties": {
"itemId": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["field"]
}
}
},
"fieldGroupSubSectionType" : {
"id": "#fieldGroupSubSectionType",
"type": "object",
"additionalProperties": false,
"properties": {
"itemId": {
"type": [ "string", "null" ]
},
"type": {
"type": "string",
"enum": [
"fieldGroup",
"subSection"
]
}
}
}
}
Any help / workaround with Sample Json Schema to achieve the above use case is appreciated.
If I understand the description of what you want correctly, then the json example you provide is not valid since it has a type: "field" but does not have an "itemId" property.
Assuming that is true. Instead of using
type: ["string", null]
use the required property.
I changed your schema a bit, instead of having separate definitions I inlined them, but other than that (and the use of required) is the same:
{
"type": "object",
"additionalProperties": false,
"properties": {
"contents": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"itemId": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"field"
]
}
},
"required": [
"itemId"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"itemId": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"fieldGroup",
"subSection"
]
}
}
}
]
}
}
}
}
Here is your answer with a little cleanup for best practices and style. The trick is that you need to use implication "a implies b <=> (not a) or b". In this case you have "type = field implies itemId is required <=> type is not field or itemId is required".
{
"type": "object",
"properties": {
"contents": {
"type": "array",
"items": { "$ref": "#/definitions/displayItem" }
}
},
"definitions": {
"displayItem": {
"type": "object",
"properties": {
"itemId": { "type": "string" },
"type": { "enum": ["field", "fieldGroup", "subSection"] }
},
"anyOf": [
{ "not": { "$ref": "#/definitions/fieldType" } },
{ "required": ["itemId"] }
]
},
"fieldType": {
"properties": {
"type": { "enum": ["field"] }
}
}
}
}
I tried searching, but I'm not quite sure how to put this in words! The point of confusion is how "required" works in JSON schema v4.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"prop1": {
"type": "array",
"items": {
"type": "object",
"properties": {
"A": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
enum:["abc","bcd"]
}
},
"required": [
"name"
]
}
}
},
"required": [
"A"
]
}
},
"prop2": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": {
"type": "string"
}
},
"required": [
"field"
]
}
}
},
"required": [
"prop1"
]
}
Here I want to set a rule that if prop1.name=="abc" then only prop2 is required otherwise prop2 is optional, how to do that ?
This is the simplified JSON-Schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "user",
"type": "object",
"properties": {
"account": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["COMPANY", "PERSON"]
}
},
"required": ["type"]
},
"person": {
"type": "object",
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" }
},
"required": ["firstName", "lastName"]
},
"company": {
"type": "object",
"properties": {
"name": { "type": "string" },
"taxNumber": { "type": "string" }
}
}
},
"required": ["account", "person"]
}
What I want to achieve is:
If account.type is set to "COMPANY":
company object and its properties should be required.
If account.type isset to "PERSON":
company object should be optional.
But if company object is present, company.name and company.taxNumber should be required.
This can be achieved by defining two long sub-schemas under a oneOf but that would mean too many duplicates and a complex schema, since account and company has many more properties than this simplified version.
AFAIK, the only way to define a specific value in a schema is by using the enum keyword with a single item. I tried this with the dependencies keyword but didn't help.
Can you think of a way without altering the structure of the data object?
You can express this requirement using switch keyword from JSON-schema v5/6 proposals that is supported in Ajv (I am the author).
Under Draft-07, you can do it by conditionally applying schema requirements:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"id": "user",
"type": "object",
"properties": {
"account": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["COMPANY", "PERSON"]
}
},
"required": ["type"]
},
"person": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
"required": ["firstName", "lastName"]
},
"company": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"taxNumber": {
"type": "string"
}
}
}
},
"if": {
"properties": {
"account": {
"const": {
"type": "COMPANY"
}
}
}
},
"then": {
"required": ["account", "person", "company"]
},
"else": {
"required": ["account", "person"]
}
}
Here's a working example that validates against it:
{
"account": {
"type": "COMPANY"
},
"person": {
"firstName": "John",
"lastName": "Doe"
},
"company": {
"name": "XYZ Corp"
}
}