JSON schema - how to specify permutations of required properties - json

Below is an extract from my JSON schema.
I want to specify that both algorithm and results are required.
Additionally I want to specify:
when algorithm is algorithm1, then results must be one of results1, results2, or results3.
when algorithm is algorithm2, then results must be one of results2, results3, or results4.
Is this possible?
"algorithm": {
"description": "description...",
"type": "string",
"enum": [
"",
"algorithm1",
"algorithm2"
]
},
"results": {
"description": "description...",
"type": "string",
"enum": [
"",
"results1",
"results2",
"results3",
"results4"
]
},
"required": ["algorithm", "results"]

Thanks to the reference above from #jruizaranguren, I was able to figure it out.
"required": ["results"],
"results": {
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/Results1" },
{ "$ref": "#/definitions/Results2" }
]
},
"definitions": {
"Results1": {
"type": "object",
"required": ["algorithm", "results"],
"properties": {
"algorithm": {
"type": "string",
"enum": [ "algorithm1" ]
},
"results": {
"type": "string",
"allOf": [
{ "result": "results1" },
{ "result": "results2" },
{ "result": "results3" }
]
}
}
},
"Results2": {
"type": "object",
"required": ["algorithm", "results"],
"properties": {
"algorithm": {
"type": "string",
"enum": [ "algorithm2" ]
},
"results": {
"type": "string",
"allOf": [
{ "result": "results2" },
{ "result": "results3" },
{ "result": "results4" }
]
}
}
}

Related

array not required returns the message: "1 item required; only 0 were given" in the json schema

I configured the json schema and it looked like this:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"organisationId": {
"type": "string"
},
"clientId": {
"type": "string"
},
"issuer": {
"oneOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"createdDate": {
"type": "string",
"format": "date-time"
},
"lastModifiedDate": {
"type": "string",
"format": "date-time"
},
"consentId": {
"type": "string"
},
"internalStatus": {
"type": "string",
"enum": [
"AUTHORISED",
"AWAITING_AUTHORISATION",
"REJECTED",
"TIMEOUT_EXPIRED",
"OVERDUE",
"REVOKED"
]
},
"permissions": {
"type": "array",
"items": [
{
"type": "string"
}
]
},
"approverType": {
"type": "string",
"enum": [
"AND",
"OR"
]
},
"status": {
"type": "string",
"enum": [
"AUTHORISED",
"AWAITING_AUTHORISATION",
"REJECTED",
"REVOKED",
"CONSUMED"
]
},
"statusUpdateDateTime": {
"type": "string",
"format": "date-time"
},
"expirationDateTime": {
"type": "string",
"format": "date-time"
},
"resourceGroups": {
"uniqueItems": true,
"oneOf": [
{
"type": "array"
},
{
"type": "null"
}
],
"items": [
{
"type": "object",
"properties": {
"resourceGroupId": {
"type": "integer"
},
"permissions": {
"type": "array",
"items": [
{
"type": "string"
}
]
},
"resources": {
"type": "array",
"uniqueItems": true,
"items": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"AVAILABLE",
"UNAVAILABLE",
"TEMPORARY_UNAVAILABLE",
"PENDING_AUTHORISATION"
]
},
"additionalInfos": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
]
},
"type": {
"type": "string",
"enum": [
"CUSTOMERS_PERSONAL_IDENTIFICATIONS",
"CUSTOMERS_PERSONAL_QUALIFICATION",
"CUSTOMERS_PERSONAL_ADITTIONALINFO",
"CUSTOMERS_BUSINESS_IDENTIFICATIONS",
"CUSTOMERS_BUSINESS_QUALIFICATION",
"CUSTOMERS_BUSINESS_ADITTIONALINFO",
"CAPITALIZATION_TITLES",
"PENSION",
"DAMAGES_AND_PEOPLE_PATRIMONIAL",
"DAMAGES_AND_PEOPLE_AERONAUTICAL",
"DAMAGES_AND_PEOPLE_NAUTICAL",
"DAMAGES_AND_PEOPLE_NUCLEAR",
"DAMAGES_AND_PEOPLE_OIL",
"DAMAGES_AND_PEOPLE_RESPONSABILITY",
"DAMAGES_AND_PEOPLE_TRANSPORT",
"DAMAGES_AND_PEOPLE_FINANCIAL_RISKS",
"DAMAGES_AND_PEOPLE_RURAL",
"DAMAGES_AND_PEOPLE_AUTO",
"DAMAGES_AND_PEOPLE_HOUSING",
"DAMAGES_AND_PEOPLE_PEOPLE",
"DAMAGES_AND_PEOPLE_ACCEPTANCE_AND_BRANCHES_ABROAD"
]
},
"hidden": {
"type": "boolean"
},
"resourceId": {
"type": "string"
}
}
}
]
},
"additionalInfos": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
}
]
},
"type": {
"type": "string",
"enum": [
"ACCOUNT",
"CREDIT_CARD_ACCOUNT",
"LOAN",
"INVOICE_FINANCING",
"UNARRANGED_ACCOUNT_OVERDRAFT",
"FINANCING",
"RESOURCE",
"CUSTOMER"
]
}
},
"required": [
"permissions",
"type"
]
}
]
},
"approvers": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"AUTHORISED",
"AWAITING_AUTHORISATION",
"REJECTED",
"REVOKED",
"CONSUMED"
]
},
"approverId": {
"type": "string"
}
},
"required": [
"approverId"
]
}
]
},
"loggedUser": {
"type": "object",
"properties": {
"document": {
"type": "object",
"properties": {
"identification": {
"type": "string"
},
"rel": {
"type": "string"
}
},
"required": [
"identification",
"rel"
]
}
},
"required": [
"document"
]
},
"businessEntity": {
"type": "object",
"properties": {
"document": {
"type": "object",
"properties": {
"identification": {
"type": "string"
},
"rel": {
"type": "string"
}
},
"required": [
"identification",
"rel"
]
}
},
"required": [
"document"
]
}
},
"required": [
"organisationId",
"clientId",
"consentId",
"permissions",
"approverType",
"status",
"statusUpdateDateTime",
"expirationDateTime",
"loggedUser"
]
},
"links": {
"type": "object",
"properties": {
"self": {
"type": "string"
},
"first": {
"type": "string"
},
"prev": {
"type": "string"
},
"next": {
"type": "string"
},
"last": {
"type": "string"
}
},
"required": [
"self"
]
},
"meta": {
"type": "object",
"properties": {
"totalRecords": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
},
"required": [
"totalRecords",
"totalPages"
]
}
}
}
Note that the "resources" array is not required, it is not mandatory.
However... when I run my test and it returns an empty array in "resources":
"resourceGroupId":1,
"permissions":[
"CUSTOMERS_PERSONAL_QUALIFICATION_READ",
"CUSTOMERS_PERSONAL_IDENTIFICATIONS_READ"
],
"resources":[],
"type":"CUSTOMER"
}
I get the following message:
"#/data/resourceGroups/0/resources: failed schema #/properties/data/properties/resourceGroups/items/0/properties/resources: 1 item required; only 0 were supplied."
I don't understand how 1 item is required if the array is not required.
and still have( "uniqueItems": true
)
which in theory would accept a [] in the return, according to the Json schema documentation.
I've tried passing minItems=0 and many other things and nothing has worked.
This looks like a combination of a bug in the validator you are using and an incorrect usage of items. The good news is that when you use items correctly, the bug will probably not apply.
The items keyword has two forms: one that takes a single schema and the other that takes an array of schemas. The form must people need most of the time is the single schema form.
{
"type": "array",
"items": { "type": "string" }
}
This schemas asserts that every item in the array is a string.
{
"type": "array",
"items": [
{ "type": "string" },
{ "type": "number" }
]
}
This schema asserts that the first item in the array is a string and the second is a number. However, it should not require that those items are present or assert anything on the rest of the items in the array. So, the bug is that your validator seems to require those values when it shouldn't.
But, that bug shouldn't affect you because you I'm sure you really meant to use the single schema version of items that validates all the items in the array against the schema. Just remove the [ and ] and your schema should work as you expected.

JSON Schema validation for different property values

I am attempting to validate the following JSON file:
{
"Transaction": {
"Header": {
"Workflow": "Rejection",
"Job-Offer": {
"Offer-Status": "New",
"Datetime-Offered": "2017-12-15T16:00:00",
"Accepted": "YES",
"Datetime-Accepted": "2017-12-15T16:00:00"
}
}
}
}
against the following schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Schema",
"description": "Schema",
"$ref": "#/defs/Schema",
"defs": {
"Schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"Transaction": {
"$ref": "#/defs/Transaction"
}
},
"required": [
"Transaction"
],
"title": "Schema"
},
"Transaction": {
"type": "object",
"additionalProperties": false,
"properties": {
"Transaction-Header": {
"$ref": "#/defs/Transaction-Header"
}
},
"required": [
"Transaction-Header"
],
"title": "Transaction"
},
"Transaction-Header": {
"type": "object",
"additionalProperties": false,
"properties": {
"Workflow": {
"type": "string",
"enum": [
"Offer",
"Transfer",
"Acceptance",
"Rejection",
"Cancellation",
"Update"
]
},
"Job-Offer": {
"$ref": "#/defs/JobOffer"
}
},
"required": [
"Workflow"
],
"title": "Transaction-Header"
},
"JobOffer": {
"description": "Job Offer.",
"type": "object",
"additionalProperties": true,
"properties": {
"Offer-Status": {
"type": "string",
"enum": [
"New",
""
]
},
"Datetime-Offered": {
"type": "string",
"format": "date-time"
},
"Accepted": {
"type": "string",
"enum": [
"YES",
"NO",
""
]
},
"Datetime-Accepted": {
"type": "string",
"format": "date-time"
},
"Reason-Rejected": {
"type": "string",
"minLength": 0,
"maxLength": 30
},
"Offer-Cancelled": {
"type": "string",
"enum": [
"YES",
"NO",
""
]
},
"Datetime-Cancelled": {
"type": "string",
"format": "date-time"
}
},
"allOf": [
{ "$ref": "#/defs/JOBACCEPT" },
{ "$ref": "#/defs/JOBREJECT" }
],
"required": [
"Offer-Status"
],
"title": "JobOffer"
},
"JOBACCEPT": {
"properties": {
"Workflow": { "enum": [ "Acceptance" ] }
},
"required": [
"Accepted",
"Datetime-Accepted"
],
},
"JOBREJECT": {
"properties": {
"Workflow": { "enum": [ "Rejection" ] }
},
"required": [
"Reason-Rejected"
],
}
}
}
What I am after is:
If the Workflow of "Acceptance" is selected, the fields under JOBACCEPT are required.
If the Workflow of "Rejection" is selected, the fields under JOBREJECT are required.
I have tried many different combinations of oneOf, allOf, anyOf, if-then-else but nothing seems to work correctly.
Anyone have any ideas what needs to be done?
Re-worked json inline:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"type": "object",
"properties": {
"Transaction": {
"type": "object",
"properties": {
"Transaction-Header": {
"type": "object",
"properties": {
"Workflow": {
"type": "string",
"enum": [
"Offer",
"Transfer",
"Acceptance",
"Rejection",
"Cancellation",
"Update"
]
},
"Job-Offer": {
"type": "object",
"properties": {
"Offer-Status": {
"type": "string",
"enum": [
"New",
""
]
},
"Datetime-Offered": {
"type": "string",
"format": "date-time"
},
"Accepted": {
"type": "string",
"enum": [
"YES",
"NO",
""
]
},
"Datetime-Accepted": {
"type": "string",
"format": "date-time"
},
"Reason-Rejected": {
"type": "string",
"minLength": 0,
"maxLength": 30
},
"Offer-Cancelled": {
"type": "string",
"enum": [
"YES",
"NO",
""
]
},
"Datetime-Cancelled": {
"type": "string",
"format": "date-time"
}
},
"required": [
"Offer-Status"
]
},
"readOnly": true
},
"required": [
"Workflow"
]
}
},
"required": [
"Transaction-Header"
]
}
},
"allOf": [
{
"if": {
"properties": {
"Transaction": {
"properties": {
"Transaction-Header": {
"properties": {
"Workflow": {
"enum": [
"Acceptance"
]
}
},
"required": [
"Workflow"
]
}
}
}
}
},
"then": {
"properties": {
"Transaction": {
"properties": {
"Transaction-Header": {
"properties": {
"Job-Offer": {
"properties": {},
"required": [
"Accepted",
"Datetime-Accepted"
]
}
}
}
}
}
}
}
}
],
"required": [
"Transaction"
]}
You had the right idea. The problem is where you've placed the allOf with your conditionals. You have it in the "JobOffer" schema, but are trying to set constraints on the "Workflow" property which is in the "Transaction-Header" schema. There is no way to reference a property that is higher up in the JSON tree structure, so you need to move the allOf up into the "Transaction-Header" schema so you can set constraints on the "Workflow" property.
Now that it's in the right place, the best way to express your conditional constraints is with if/then. The context of the if/then is now the the "Transaction-Header" schema, so the then schemas needs to not just say what properties are required, they need to declare that those properties are in the "Job-Offer" object.
{
...
"defs": {
...
"Transaction-Header": {
...
"allOf": [
{ "$ref": "#/defs/JOBACCEPT" },
{ "$ref": "#/defs/JOBREJECT" }
]
},
"JOBACCEPT": {
"if": {
"type": "object",
"properties": {
"Workflow": { "enum": ["Acceptance"] }
},
"required": ["Workflow"]
},
"then": {
"properties": {
"Job-Offer": {
"required": ["Accepted", "Datetime-Accepted"]
}
}
}
},
"JOBREJECT": { ... Similar to JOBACCEPT ... }
}
}
You're abstracting everything away into definitions *, so it's tricky to express conditionals that reference things multiple layers deep. If you inline all the definitions, it gets a little easier to see what needs to be done.
The if/then keywords need to be at the level of 'Transaction'. In pseudocode:
"if the property 'Header' exists (i.e. required) and its value is ... (const), then require property ... with value (type=object, required properties=[...], property definitions=...)", and so on.
* by the way, in version 2020-12 the definitions keyword is $defs -- it may work the way you have it, but implementations will be unable to validate the schemas undef defs as they won't recognize them there, so some errors can slip through and be harder to find.

Assistance needed to create JSON schema

As I am new to JSON schema creation, I have learnt the basics of JSON schema and now I am trying to create JSON schema for the below mentioned set of data,
{
"Result": [
{
"ResourceName": "Appointment",
"Sequence": "1",
"Data": {
"AppointmentID": "A1234",
"PatientName": "Test Patient",
"ClinicName": "Test Clinic"
}
},
{
"ResourceName": "EpisodeofCare",
"Sequence": "2",
"Data": {
"EpisodeID": "EP1234",
"LocationId": "L1234",
"AppointmentId": "A1234",
"TransactionStatus": "2",
"OPNumber": "OP523367"
}
},
{
"ResourceName": "Encounter",
"Sequence": "3",
"Data": {
"EncounterID": "E1234",
"PatientID": "P1234"
}
}
]
}
Can anybody please help me to create JSON schema for this kind of data set.
Thanks in advance for helping me out on this.
Below is the JSON schema i have drafted
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ResultType": {
"type": "object",
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string"
},
"Data": {
"type": "object",
"anyOf": [
{
"$ref": "#/definitions/Appointment"
},
{
"$ref": "#/definitions/EpisodeofCare"
},
{
"$ref": "#/definitions/Encounter"
}
]
}
}
},
"Appointment": {
"type": "object",
"properties": {
"AppointmentID": {
"type": "boolean"
},
"PatientName": {
"type": "string"
},
"ClinicName": {
"type": "string"
}
}
},
"EpisodeofCare": {
"type": "object",
"properties": {
"EpisodeID": {
"type": "string"
},
"LocationId": {
"type": "string"
},
"AppointmentId": {
"type": "string"
},
"TransactionStatus": {
"type": "string"
},
"OPNumber": {
"type": "string"
}
}
},
"Encounter": {
"type": "object",
"properties": {
"EncounterID": {
"type": "string"
},
"PatientID": {
"type": "string"
}
}
}
},
"type": "object",
"properties": {
"Result": {
"type": "array",
"$ref": "#/definitions/ResultType"
}
}
}
Throw it in a schema validator like this one.
You will see errors in your schemas definition and in validation.
First of all check that your schema is valid json (the validator might help):
[
{
{"$ref": "#/definitions/Appointment"} <- unnecessary and invalid braces
},
{
{"$ref": "#/definitions/EpisodeofCare"} <- unnecessary and invalid braces
},
{
{"$ref": "#/definitions/Encounter"} <- unnecessary and invalid braces
}
]
Within the Result property you want each item of the array. You should use the item property instead of ref. As taken from the specification:
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.
Thus you should use
{
"type": "object",
"properties": {
"Result": {
"type": "array",
"items": {
"$ref": "#/definitions/ResultType"
}
}
}
}
Since the schema should be as specific as possible you should constraint the content of the ResourceName properties to the actual data layout.
Use the const property to define a constant value for the ResourceName for each type of Resource. Take for example the Appointment type, which would change to:
"Appointment": {
"type": "object",
"properties": {
"ResourceName": {
"const": "Appointment"
},
"Data": {
"type": "object",
"properties": {
"AppointmentID": {
"type": "string"
},
"PatientName": {
"type": "string"
},
"ClinicName": {
"type": "string"
}
}
}
}
I also changed the type of AppointmentID to string.
Then your ResultType needs to be adjusted. Before you used anyOf to validate the data, now you need it to validate the complete object while still maintaining the overall structure:
"ResultType": {
"allOf": [
{
"type": "object",
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string"
},
"Data": true
}
},
{
"anyOf": [
{
"$ref": "#/definitions/Appointment"
},
{
"$ref": "#/definitions/EpisodeofCare"
},
{
"$ref": "#/definitions/Encounter"
}
]
}
]
}
The allOf propertiy implies a and condition. The overall structure (the object) does not care what value ResourceName has or how Data is structured. The specific implementations (the anyOf part) take care of that.
Some final improvements. Use the required property to define the names of properties that must exist in your JSON file. Also add "additionalProperties": false to ensure that only the specified properties are used. And finally constraint your sequence values to be string representations of positive intergers by adding "pattern": "[1-9]\\d*".
Final result:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ResultType": {
"allOf": [
{
"type": "object",
"required": [
"ResourceName",
"Sequence",
"Data"
],
"additionalProperties": false,
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string",
"pattern": "[1-9]\\d*"
},
"Data": true
}
},
{
"anyOf": [
{
"$ref": "#/definitions/Appointment"
},
{
"$ref": "#/definitions/EpisodeofCare"
},
{
"$ref": "#/definitions/Encounter"
}
]
}
]
},
"Appointment": {
"type": "object",
"properties": {
"ResourceName": {
"const": "Appointment"
},
"Data": {
"type": "object",
"required": [
"AppointmentID",
"PatientName",
"ClinicName"
],
"additionalProperties": false,
"properties": {
"AppointmentID": {
"type": "string"
},
"PatientName": {
"type": "string"
},
"ClinicName": {
"type": "string"
}
}
}
}
},
"EpisodeofCare": {
"type": "object",
"properties": {
"ResourceName": {
"const": "EpisodeofCare"
},
"Data": {
"type": "object",
"required": [
"EpisodeID",
"LocationId",
"AppointmentId",
"TransactionStatus",
"OPNumber"
],
"additionalProperties": false,
"properties": {
"EpisodeID": {
"type": "string"
},
"LocationId": {
"type": "string"
},
"AppointmentId": {
"type": "string"
},
"TransactionStatus": {
"type": "string"
},
"OPNumber": {
"type": "string"
}
}
}
}
},
"Encounter": {
"type": "object",
"properties": {
"ResourceName": {
"const": "Encounter"
},
"Data": {
"type": "object",
"required": [
"EncounterID",
"PatientID"
],
"additionalProperties": false,
"properties": {
"EncounterID": {
"type": "string"
},
"PatientID": {
"type": "string"
}
}
}
}
}
},
"type": "object",
"required": [
"Result"
],
"additionalProperties": false,
"properties": {
"Result": {
"type": "array",
"items": {
"$ref": "#/definitions/ResultType"
}
}
}
}
you can create json schema by online tools which generates json schema from the json
like: https://www.liquid-technologies.com/online-json-to-schema-converter , it also checks if json is valid or not.
Json Schema that you need:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"Result": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string"
},
"Data": {
"type": "object",
"properties": {
"AppointmentID": {
"type": "string"
},
"PatientName": {
"type": "string"
},
"ClinicName": {
"type": "string"
}
},
"required": [
"AppointmentID",
"PatientName",
"ClinicName"
]
}
},
"required": [
"ResourceName",
"Sequence",
"Data"
]
},
{
"type": "object",
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string"
},
"Data": {
"type": "object",
"properties": {
"EpisodeID": {
"type": "string"
},
"LocationId": {
"type": "string"
},
"AppointmentId": {
"type": "string"
},
"TransactionStatus": {
"type": "string"
},
"OPNumber": {
"type": "string"
}
},
"required": [
"EpisodeID",
"LocationId",
"AppointmentId",
"TransactionStatus",
"OPNumber"
]
}
},
"required": [
"ResourceName",
"Sequence",
"Data"
]
},
{
"type": "object",
"properties": {
"ResourceName": {
"type": "string"
},
"Sequence": {
"type": "string"
},
"Data": {
"type": "object",
"properties": {
"EncounterID": {
"type": "string"
},
"PatientID": {
"type": "string"
}
},
"required": [
"EncounterID",
"PatientID"
]
}
},
"required": [
"ResourceName",
"Sequence",
"Data"
]
}
]
}
},
"required": [
"Result"
]
}

json schema definition using conditional statements

Iam trying to define an optional condition using json schema conditional statement (Using draft 7)
I have a json response like this.
[{
"views": [{
"name": "RSO Roster",
"displayOrder": 5,
"groups": [{
"type": "scrollable",
"displayOrder": 1,
"auditType": "player-pregame_roster",
"tiles": [{
"context": "event",
"dataStamp": 1535184247,
"tile_type": "person"
}, {
"context": "event",
"errorCode": 2,
"errorText": "seloger",
"tile_type": "person"
}
]
}
]
},
{
"name": "Leaders",
"displayOrder": 1,
"groups": [{
"type": "static",
"displayOrder": 1,
"tiles": [{
"context": "event",
"dataStamp": 1535184247,
"eventId":123
"tile_type": "static"
}
]
}
]
}
]
}]
In this response if the tile object contains the key errorCode the required field must be errorText and errorCode keys.Like wise
if the tile object doessnot contains any "errorCode" or "errorText" key then the tile item contains the required field "dataStamp".
To validate the above condition i have defined a schema like below.But it is not working.Whats wrong with my schema .
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"views": {
"$id": "views",
"type": "array",
"items": {
"$id": "views/items",
"type": "object",
"properties": {
"groups": {
"$id": "views/groups",
"type": "array",
"items": {
"$id": "views/groups/items",
"type": "object",
"properties": {
"tiles": {
"$id": "views/groups/tiles",
"type": "array",
"items": {
"$id": "views/groups/tiles/items",
"type": "object",
"properties": {
"dataStamp": {
"$id": "views/groups/tiles/dataStamp",
"type": "integer"
},
"tile_type": {
"$id": "views/groups/tiles/tile_type",
"type": "string"
},
"errorCode": {
"type": "integer",
"enum": [
2, 10
]
},
"errorText": {
"type": "string",
"enum": [
"seloger", "france24"
]
}
},
"if": {
"properties": {
"tile_type": {
"enum": ["person"]
},
"errorCode": {
"enum": [2, 10]
}
},
"required": ["errorCode", "errorText"]
}
}
}
},
"required": [
"type",
"tiles"
]
}
}
},
"required": [
"groups"
]
}
}
},
"required": [
"views"
]
}
}
The if statement is missing required in properties:
"if": {
"properties": {
"tile_type": {
"enum": ["person"]
},
"errorCode": {
"enum": [2, 10]
},
"required": ["errorCode"]
}
},
If there is no required the value of property is validated only if the property is set. So original if schema would pass any object without tile_type and errorCode.
https://stackoverflow.com/a/51034071/329463 might give you some inspiration on building exclusive properties clusters.
EDIT: modified full schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"views": {
"$id": "views",
"type": "array",
"items": {
"$id": "views/items",
"type": "object",
"properties": {
"groups": {
"$id": "views/groups",
"type": "array",
"items": {
"$id": "views/groups/items",
"type": "object",
"properties": {
"tiles": {
"$id": "views/groups/tiles",
"type": "array",
"items": {
"$id": "views/groups/tiles/items",
"type": "object",
"properties": {
"dataStamp": {
"$id": "views/groups/tiles/dataStamp",
"type": "integer"
},
"tile_type": {
"$id": "views/groups/tiles/tile_type",
"type": "string"
},
"errorCode": {
"type": "integer",
"enum": [
2, 10
]
},
"errorText": {
"type": "string",
"enum": [
"seloger", "france24"
]
}
},
"if": {
"properties": {
"tile_type": {
"enum": ["person"]
},
"errorCode": {
"enum": [2, 10]
}
},
"required":["errorCode"]
},
"then": {
"required": ["errorCode", "errorText"]
},
"else": {
"required": ["dataStamp"]
}
}
}
},
"required": [
"type",
"tiles"
]
}
}
},
"required": [
"groups"
]
}
}
},
"required": [
"views"
]
}
}

Json schema auto completion property

I have already created my own schema on intellij environment, and it's working good, but still have problems in auto completion which provides intellij to the schema,
for example if object "car" defined in json schema then intellij can recognize that there's such object in the schema and intellij will give it as suggestion through out coding json, the problem that I'm facing is that the suggestions are contains all the objects that defined in the schema, but the expectations are to get the objects which defined under the scoop of another object
This is some code of my own schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Pipe File",
"type": "object",
"definitions": {
"Pipe": {
"type": "object",
"properties": {
"components": {
"$ref": "#/definitions/components"
}
},
"required": [
"components"
]
},
"components": {
"description": "section which defines the pipes in the file",
"type": "array",
"minItems": 1,
"items": {
"oneOf": [
{
"$ref": "#/definitions/setValuesComponent"
},
{
"$ref": "#/definitions/invokeWebServicesComp"
}
]
}
},
"setValuesComponent": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"enum": [
"setValuesComp"
]
},
"out": {
"type": "object",
"properties": {
"dateFormat": {
"$ref": "#/definitions/setValuesCompOut"
},
"dateTimeFormat": {
"$ref": "#/definitions/setValuesCompOut"
},
"dateFormatBank": {
"$ref": "#/definitions/setValuesCompOut"
}
}
},
"condition": {
}
},
"required": [
"name",
"type",
"out"
]
},
"setValuesCompOut": {
"type": "object",
"properties": {
"exprValue": {
"type": "string"
},
"ctxEntry": {
"type": "string"
},
"value": {
"type": "string"
},
"exprConst": {
"type": "string",
"pattern": "(Class|class)\\.\\w+\\.\\w+"
}
},
"anyOf": [
{
"required": [
"exprValue"
]
},
{
"required": [
"ctxEntry"
]
},
{
"required": [
"value"
]
},
{
"required": [
"exprConst"
]
}
]
},
"invokeWebServicesComp": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"enum": [
"invokeWebServices"
]
},
"mode": {
"enum": [
"innerJoin",
"leftJoin",
"union",
"parallelJoin"
]
},
"method": {
"type": "string"
},
"headers": {
"$ref": "#/definitions/invokeWebServicesCompHeaders"
},
"dataFilePath": {
"type": "string"
},
"restRelativeUrl": {
"type": "string"
},
"in": {
"$ref": "#/definitions/invokeWebServicesCompIn"
},
"out": {
"$ref": "#/definitions/invokeWebServicesCompOut"
}
},
"required": [
"type",
"name",
"out",
"in"
]
},
"invokeWebServicesCompOut": {
"type": "object",
"patternProperties": {
"doc": {
"type": "string",
"pattern": ".+"
}
}
},
"invokeWebServicesCompHeaders": {
"type": "object",
"patternProperties": {
".{1,}": {
"type": "string",
"pattern": ".+"
}
}
},
"invokeWebServicesCompIn": {
"type": "object",
"patternProperties": {
".{1,}": {
"type": "string",
"pattern": ".+"
}
}
},
"properties": {
"pipes": {
"description": "section which defines the mandatory pipes object in the file",
"type": "object",
"patternProperties": {
".{1,}": {
"$ref": "#/definitions/Pipe"
}
}
}
},
"required": [
"pipes"
]
}
}
So what I expected is, when the type of object determined to "setValuesComp", the auto completion will suggest the relevant properties, that's mean it will not suggest "in" property which is belong to "invokeWebServicesComp" not "setValuesComponent".this picture show the auto complete problem in my real environment
Your JSON schema seems to be invalid. The below JSON content should be present inside object type.
"properties": {
"pipes": {
"description": "section which defines the mandatory pipes object in the file",
"type": "object",
"patternProperties": {
".{1,}": {
"$ref": "#/definitions/Pipe"
}
}
}
},
"required": [
"pipes"
]
In your schema, it is present as part of the "definitions". Please make this correction and then check if you are able to get the suggestions.