Json validation oneof validation - json

So I had this json
{
"f1":"John",
"f2":"whatever",
"f3":"abc"
}
I wanted to validate it as only one of f1, f2, f3 should be present. If neither f1, f2 and f3 are present then it should pass.
Something like,
{
"f1":"John",
}
PASS
{
"f1":"John",
"f2":"whatever",
}
FAIL
{
"f1":"John",
"f2":"whatever",
"f3":"abc"
}
FAIL
{}
PASS
Here is the code I wrote but it is failing
{
"allOf": [
{
"if": {
"required": [
"f1"
]
},
"then": {
"not": {
"required": [
"f2", "f3"
]
}
}
},
{
"if": {
"required": [
"f3"
]
},
"then": {
"not": {
"required": [
"f2", "f1"
]
}
}
},
{
"if": {
"required": [
"f2"
]
},
"then": {
"not": {
"required": [
"f3", "f1"
]
}
}
}
]
}
EDIT:
snippet of schema https://jsonschema.dev/s/eN6Db

From your requirements as given, you don't need to check against the other properties as they are defined. A schema like this would be sufficient:
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
"properties": {
"f1": {
"type": "string"
},
"f2": {
"type": "string"
},
"f3": {
"type": "string"
}
},
"minProperties": 0,
"maxProperties": 1,
"additionalProperties": false
}
However, this does not work if you also need other properties at this level.

You have two options here.
You can add else: false to each of your subschemas (demo)
OR, remove the conditional checks and use oneOf. You'd have to also add a subschema to allow for empty objects. The second approach may be preferable.
Here's the schema and a demo.
{
"oneOf": [
{
"additionalProperties": false
},
{
"required": [
"f1"
],
"not": {
"required": [
"f2",
"f3"
]
}
},
{
"required": [
"f3"
],
"not": {
"required": [
"f2",
"f1"
]
}
},
{
"required": [
"f2"
],
"not": {
"required": [
"f3",
"f1"
]
}
}
]
}

There's a concise little trick to express this kind of constraint using the dependencies (or dependentSchemas if >= 2019-09) keyword.
{
"type": "object",
"properties": {
"f1": {},
"f2": {},
"f3": {}
},
"dependencies": {
"f1": { "not": { "required": ["f2"] } },
"f2": { "not": { "required": ["f3"] } },
"f3": { "not": { "required": ["f1"] } }
}
}

Related

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.

JSON is not getting validated based on schema

I must be missing something here, but the below JSON is not getting validated against the schema.
For example, the required attribute from the Java/JavaScript object is never getting enforced as per the schema. (FYI- Every language object may have other attributes or nested object)
However, if I completely remove the definition and directly put under array items each separately, then it validates.
I want to use 'definitions' and gets validated.The reason I have to put all the object in definitions and later I may have to put different language object in oneOf/allOf for other certain validation check.
Online check:
Schema and JSON
JSON
{
"languages": [
{
"lang": "Java",
"trainer": "Peter"
},
{
"lang": "JavaScript",
"enrolled": "42",
"available": "5"
}
]
}
and the Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"languages"
],
"properties": {
"languages": {
"type": "array",
"minItems": 1,
"items": {
"type": "object"
},
"anyOf": [
{
"$ref": "#/definitions/Java"
},
{
"$ref": "#/definitions/JavaScript"
}
]
}
},
"definitions": {
"Java": {
"required": [
"trainer"
],
"properties": {
"lang": {
"enum": [
"Java"
]
},
"trainer": {
"type": "string"
}
}
},
"JavaScript": {
"required": [
"enrolled",
"available"
],
"properties": {
"lang": {
"enum": [
"JavaScript"
]
},
"enrolled": {
"type": "string"
},
"available": {
"type": "string"
}
}
}
}
}
The fixed schema and it works now
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"languages"
],
"properties": {
"languages": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"anyOf": [
{
"$ref": "#/definitions/Java"
},
{
"$ref": "#/definitions/JavaScript"
}
]
}
}
},
"definitions": {
"Java": {
"required": [
"trainer"
],
"properties": {
"lang": {
"enum": [
"Java"
]
},
"trainer": {
"type": "string"
}
}
},
"JavaScript": {
"required": [
"enrolled",
"available"
],
"properties": {
"lang": {
"enum": [
"JavaScript"
]
},
"enrolled": {
"type": "string"
},
"available": {
"type": "string"
}
}
}
}
}
I think that the "array" definition is not correct. The objects that can be added in the array must be refereed in the "items", after you define the type of the items. Something like this:
"languages": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"anyOf": [
{"$ref": "#/definitions/Java"},
{"$ref": "#/definitions/JavaScript"}
]
}
}
I have fixed myself
What I did: I have placed the json object blocks under items section of array.

Why is my use of JSON Schema `allOf` keyword not validating correctly?

I am running into more children objects that are not validating correctly (object.actor, object.verb, object.object). I tried looking for any empty schema after changing my if/then structures in the object schema to if/then/else adding the false value for each else. I did not find anything obvious.
JSON -Should fail but doesn't
{
"actor": {
"objectType": "Agent",
"name": "xAPI account",
"mbox": "mailto:xapi#adlnet.gov"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/attended",
"display": {
"en-GB": "attended",
"en-US": "attended"
}
},
"object": {
"objectType": "SubStatement",
"actor": {
"objectType": "should fail",
"name": "xAPI mbox",
"mbox": "mailto:should fail"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/reported",
"display": {
"should fail": "reported",
"en-US": "reported"
}
},
"object": {
"objectType": "Activity",
"id": "should fail"
}
}
}
JSON - Fails at the root level only; substatement values are not checked. assuming empty schema coming from somewhere.
{
"actor": {
"objectType": "Agent",
"name": "xAPI account",
"mbox": "this fails"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/attended",
"display": {
"this fails": "attended",
"en-US": "attended"
}
},
"object": {
"objectType": "SubStatement",
"actor": {
"objectType": "should fail",
"name": "xAPI mbox",
"mbox": "mailto:should fail"
},
"verb": {
"id": "http://adlnet.gov/expapi/verbs/reported",
"display": {
"should fail": "reported",
"en-US": "reported"
}
},
"object": {
"objectType": "Activity",
"id": "should fail"
}
}
}
JSON SCHEMA (stripped to the bone)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "xAPIValidator",
"description": "Validation schema for xAPI tests",
"type": "object",
"allOf": [
{
"$ref": "#/definitions/Statement"
},
{
"statements": [
{
"$ref": "#/definitions/Statement"
}
]
}
],
"definitions": {
"Statement": {
"additionalProperties": false,
"properties": {
"objectType": {
"type:": "string",
"enum": [
"Agent",
"Activity",
"Group",
"SubStatement",
"StatementRef"
]
},
"id": {
"allOf": [
{
"$ref": "#/definitions/uuid"
}
]
},
"actor": {
"$id": "#actor",
"allOf": [
{
"$ref": "#/definitions/allOfAgentGroup"
}
]
},
"verb": {
"$id": "#verb",
"type": "object",
"properties": {
"id": {
"allOf": [
{
"$ref": "#/definitions/URI"
}
]
},
"display": {
"type": "object",
"allOf": [
{
"$ref": "#/definitions/lang5646"
}
]
}
}
},
"object": {
"$id": "#object",
"type": "object",
"properties": {
"objectType": {
"type:": "string",
"enum": [
"Activity",
"Agent",
"Group",
"SubStatement",
"StatementRef"
]
}
},
"oneOf": [
{
"if": {
"properties": {
"objectType": {
"const": "SubStatement"
}
}
},
"then": {
"$comment": "Substatement object type",
"allOf": [
{
"$ref": "#/definitions/Statement"
}
],
"allOf": [
{
"not": {
"required": [
"id"
]
}
},
{
"not": {
"required": [
"authority"
]
}
},
{
"not": {
"required": [
"stored"
]
}
},
{"required":["actor","verb","object"]}
]
},
"else": false
}
]
}
},
"required": [
"actor",
"verb",
"object"
]
},
"Agent": {
"$id": "#Agent",
"maxProperties": 3,
"allOf": [
{
"$ref": "#/definitions/IFI"
}
]
},
"AnonGroup": {
"$id": "#AnonGroup",
"maxProperties": 3,
"properties": {
"member": {
"type": "array",
"items": [
{
"allOf": [
{
"$ref": "#/definitions/allOfAgentGroup"
}
]
}
]
}
},
"dependencies": {
"objectType": [
"member"
]
},
"required": [
"member"
],
"not": {
"required": [
"mbox"
]
},
"not": {
"required": [
"mbox_sha1sum"
]
},
"not": {
"required": [
"openid"
]
},
"not": {
"required": [
"account"
]
}
},
"IdGroup": {
"$id": "#IdGroup",
"maxProperties": 4,
"properties": {
"member": {
"type": "array",
"items": [
{
"oneOf": [
{
"$ref": "#/definitions/allOfAgentGroup"
}
]
}
]
}
},
"oneOf": [
{
"$ref": "#/definitions/IFI"
}
]
},
"allOfAgentGroup": {
"properties": {
"objectType": {
"type": "string",
"enum": [
"Agent",
"Group"
]
},
"name": {
"type": "string"
}
},
"oneOf": [
{
"if": {
"properties": {
"objectType": {
"const": "Agent"
}
}
},
"then": {
"allOf": [
{
"$ref": "#/definitions/Agent"
}
]
},
"else": false
},
{
"if": {
"properties": {
"objectType": {
"const": "Group"
}
}
},
"then": {
"oneOf": [
{
"allOf": [
{
"$ref": "#/definitions/IdGroup"
}
]
},
{
"allOf": [
{
"$ref": "#/definitions/AnonGroup"
}
]
}
]
},
"else": false
}
]
},
"IFI": {
"oneOf": [
{
"properties": {
"mbox": {
"allOf": [
{
"$ref": "#/definitions/mailto"
}
]
}
},
"required": [
"mbox"
]
},
{
"properties": {
"mbox_sha1sum": {
"type": "string",
"pattern": "\\b[0-9a-f]{5,40}\\b"
}
},
"required": [
"mbox_sha1sum"
]
},
{
"properties": {
"account": {
"properties": {
"homePage": {
"allOf": [
{
"$ref": "#/definitions/URI"
}
]
},
"name": {
"type": "string"
}
},
"required": [
"homePage",
"name"
]
}
},
"required": [
"account"
]
},
{
"properties": {
"openid": {
"allOf": [
{
"$ref": "#/definitions/URI"
}
]
}
},
"required": [
"openid"
]
}
]
},
"mailto": {
"type": "string",
"pattern": "(mailto:)(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
},
"URI": {
"type": "string",
"pattern": "^(https?|ftp|file)://[-a-zA-Z0-9+&##/%?=~_|!:,.;]*[-a-zA-Z0-9+&##/%=~_|]"
},
"uuid": {
"type": "string",
"pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
},
"lang5646": {
"type": "object",
"patternProperties": {
"^((?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?:([A-Za-z]{2,3}(-(?:[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?:[A-Za-z]{4}))?(-(?:[A-Za-z]{2}|[0-9]{3}))?(-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?:[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?:x(-[A-Za-z0-9]{1,8})+))?)|(?:x(-[A-Za-z0-9]{1,8})+))$": {
"type": "string"
}
},
"additionalProperties": false
},
"lang5646string": {
"type": "string",
"pattern": "^((?:(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?:([A-Za-z]{2,3}(-(?:[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?:[A-Za-z]{4}))?(-(?:[A-Za-z]{2}|[0-9]{3}))?(-(?:[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?:[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?:x(-[A-Za-z0-9]{1,8})+))?)|(?:x(-[A-Za-z0-9]{1,8})+))$"
}
}
}
In "$id": "#object" > oneOf > then, you define allOf twice in that JSON object.
The behaviour of duplicate keys in JSON is undefined.
Often the way it's handled is just to take the last occurrence of each key for an object.
You can see this working by having the following schema and an empty object instance: {}
Schema :
{
"allOf": [
false
],
"allOf": [
true
]
}
The JSON library will likely ignore the first allOf, taking the last occurrence, resulting in allways pass validation. Swap the true and false to double confirm.
Any time you've used a specific *of keyword more than once in the same object in the schema (or any key more than once in an object), you'll need to fix it.

JSON Schema make property conditionally required

My current JSON schema definition is like this
{
"properties": {
"account_type": {
"description": "account type",
"enum": [
"CURRENT",
"SAVINGS",
"DEMAT"
],
"type": "string"
},
"demat_account_number": {
"description": "demat_account_number",
"type": "string"
}
},
"required": [
"account_type"
],
"type": "object"
}
My requirement is if "account_type" = "DEMAT" then "demat_account_number" should become a required attribute.
Is there any way we can achieve this validation?
You can use "oneOf". This forces conforming documents to implement only one of a number of possible patterns:
{
"oneOf":[
{
"properties":{
"account_type":{
"description":"account type",
"enum":[
"CURRENT",
"SAVINGS"
],
"type":"string"
}
},
"required":[
"account_type"
],
"type":"object"
},
{
"properties":{
"account_type":{
"description":"account type",
"enum":[
"DEMAT"
],
"type":"string"
},
"demat_account_number":{
"description":"demat_account_number",
"type":"string"
}
},
"required":[
"account_type",
"demat_account_number"
],
"type":"object"
}
]
}
A nice option is to use a if/then. The if block uses the const assertion to verify that account_type has the "DEMAT" value. The then block adds the demat_account_number to the required properties.
{
"properties": {
"account_type": {
},
"demat_account_number": {
}
},
"required": [
"account_type"
],
"if": {
"properties": {
"account_type": {
"const": "DEMAT"
}
}
},
"then": {
"required": [
"demat_account_number"
]
}
}

Json schema oneOf with additionalProperties draft-04

I am trying to make a schema for validating a policy language. Short:
a policy is associated with an assertion. This assertion can either be an operator (and, or, not) and contains a list of other assertions. An assertion can also be a primitive (leaf node).
I made an UML design to make things easier to understand:
UML diagram
{
"policy": {
"name": "test",
"expression": {
"operator": "all",
"value": [
{
"primitive": "encrypt",
"preference": 12345,
"usage": "required"
},
{
"primitive": "sign",
"preference": 12345,
"usage": "required"
}
],
"preference": 12345,
"usage": "required"
}
}
}
And here is the scheme I currenty made:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"minProperties": 1,
"additionalProperties": {
"$ref": "#/definitions/policy"
},
"definitions": {
"policy": {
"title": "Policy",
"type": "object",
"required": [
"name",
"expression"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string"
},
"expression": {
"$ref": "#/definitions/assertion"
}
}
},
"operator": {
"properties": {
"value": {
"type": "array",
"items": {
"$ref": "#/definitions/assertion"
}
},
"operator": {
"enum": [
"allOne",
"all"
]
}
}
},
"primitive": {
"properties": {
"primitive": {
"enum": [
"encrypt",
"sign"
]
}
}
},
"assertion": {
"type": "object",
"additionalProperties": false,
"oneOf": [
{
"$ref": "#/definitions/operator"
},
{
"$ref": "#/definitions/primitive"
}
],
"properties": {
"preference": {
"type": "integer",
"minimum": 0,
"exclusiveMinimum": true
},
"usage": {
"enum": [
"required",
"rejected",
"optional",
"observed",
"ignored"
]
}
}
}
}
}
With the use of "oneOf" I'm trying to either use the specification of an operator or a primitive. But I'm not sure this is the way to go because i received the following error:
"message" : "object instance has properties which are not allowed by the schema: [\"operator\",\"value\"]"
The error message complains about extra properties which are not defined (because of "additionalProperties": false). However, these are defined in the definitions...
The oneOf, anyOf, ... keywords cannot be used for referencing other definitions. They do work for required. The solution is to declare all properties and only require the properties that are needed in the context. My example would become the following:
"assertion": {
"type": "object",
"additionalProperties": false,
"oneOf": [
{
"required": [
"operator"
]
},
{
"required": [
"primitive"
]
}
],
"properties": {
"operator": {
"$ref": "#/definitions/operator"
},
"primitive": {
"$ref": "#/definitions/primitive"
},
"preference": {
"type": "integer",
"minimum": 0,
"exclusiveMinimum": true
},
"usage": {
"enum": [
"required",
"rejected",
"optional",
"observed",
"ignored"
]
}
}
}