M Miller
M Miller

Reputation: 5662

JSON schema - valid if object does *not* contain a particular property

Is it possible to set up a JSON schema that still allows for additionalProperties but does not match if a very particular property name is present? In other words, I need to know if it's possible to have the exact opposite of the required declaration.

Schema:

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "ban": [ "z" ] // possible?
}

Match:

{ "x": 123 }

Match:

{ "x": 123, "y": 456 }

Do not match:

{ "x": 123, "y": 456, "z": 789 }

Upvotes: 52

Views: 37814

Answers (5)

swarnim gupta
swarnim gupta

Reputation: 231

You can have type null for that particular property :

 z : {
"type": "null"
}

Upvotes: -2

jruizaranguren
jruizaranguren

Reputation: 13635

There is a simpler approach. Define that if x is present it must not satisfy any schema. By reduction to absurdity x can not be present:

{
    "properties" : {
        "x" : {
            "not" : {}

        }
    }
}

Update 2020/04/16: As pointed out by @Carsten in a comment, from draft version 05 and above, the proposed schema can be simplified as follows:

{
    "properties": {
       "x": false
    }
}

Upvotes: 50

Tomás Senart
Tomás Senart

Reputation: 1433

To specify the absence of a field, you can expect it's type to be null.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" },
        "z": { "type": "null" }

    },
    "required": [ "x" ]
}

Upvotes: 6

Jason Desrosiers
Jason Desrosiers

Reputation: 24489

What you want to do can be achieved using the not keyword. If the not schema validates, the parent schema will not validate.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "not": { "required": [ "z" ] }
}

Upvotes: 60

M Miller
M Miller

Reputation: 5662

I solved the issue by banning additional properties via "additionalProperties": false but using patternProperties to allow any property name except the banned one.

{
    "type": "object",
    "properties": {
        "x": { "type": "integer" }
    },
    "required": [ "x" ],
    "patternProperties": {
        "^(?!^z$).*": {}
    },
    "additionalProperties": false
}

Upvotes: 6

Related Questions