What is the difference between "anyof" and "oneof" in z schema?
Asked Answered
A

3

20

Its looking like both works fine with my input validation code. Then what is the exact difference?

Schema with oneof

[{
  "id": "MyAction",
  "oneOf": [{ "$ref": "A1" },
            { "$ref": "A2" }]
 },
 {
  "id": "A1",
  "properties": {
      "class1": { "type": "string"},
      "class2": { "type": "string"}
   }
 },
 {
  "id": "A2",
  "properties": {
      "class2": { "type": "string"},
      "class3": { "type": "string"}
   }
 }
]

Schema with anyof

    [{
  "id": "MyAction",
  "anyOf": [{ "$ref": "A1" },
            { "$ref": "A2" }]
 },
 {
  "id": "A1",
  "properties": {
      "class1": { "type": "string"},
      "class2": { "type": "string"}
   }
 },
 {
  "id": "A2",
  "properties": {
      "class2": { "type": "string"},
      "class3": { "type": "string"}
   }
 }
]
Antananarivo answered 2/12, 2015 at 8:40 Comment(1)
What does the documentation say? What part of that documentation are you having trouble with?Broadside
B
35

If you look at the JSON Schema documentation, it says:

anyOf:

...

An instance validates successfully against this keyword if it validates successfully against at least one schema defined by this keyword's value. Note that when annotations are being collected, all subschemas MUST be examined so that annotations are collected from each subschema that validates successfully.

oneOf:

...

An instance validates successfully against this keyword if it validates successfully against exactly one schema defined by this keyword's value.

Note my emphasis in the above. anyOf means the item must validate against at least one (but possibly more than one) of the schemas. oneOf means it must validate against only one of the schemas.

Broadside answered 2/12, 2015 at 8:45 Comment(4)
Ha Ha ha... nice... that means.... oneof = writing so many if and else statement one after another and anyof = writing if and elseif... :) isn't it?Antananarivo
@Somnath: I'm having trouble understanding that question, but if I am understanding it, you have it backward. anyOf would require that the item be tested against each of the schemas until it matched at least one, and then the later schemas could be ignored (doesn't matter if it matches them or not). oneOf means the item needs to be tested against each schema even after it matches one, and if it matches another one, the test needs to fail.Broadside
Exactly. Thank you very much @T.J. CrowderAntananarivo
I think the confusion for me at least was that I was defining type as string, so anyOf doesn't make sense: It's not an array, but a single-value.Boatwright
F
10

I am late in the quest but as per my understanding the usage of this keyword depends on the type of the object/parent itself. for example if you are trying to define the type for a single property of the object or the element of an array. take the below example :

{
    "title": "Sample JSON Schema",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "definitions": {
        "propObjectType1" : {
            "name": "string",
            "age": "number"
        },
        "propObjectType2" : {
            "name": "string",
            "dob": {
                "type": "string",
                "pattern": "\\d\\d\/\\d\\d\/\\d\\d\\d\\d"
            }
        }
    },
    "properties": {
        "prop1": {
            "type": "string",
            "maxLength": 64
        },
        "prop2": {
            "anyOf": [
                {
                    "$ref": "#/definitions/propObjectType1"
                },
                {
                    "$ref": "#/definitions/propObjectType2"
                }
            ] 
        },
        "prop3": {
            "oneOf": [
                {
                    "$ref": "#/definitions/propObjectType1"
                },
                {
                    "$ref": "#/definitions/propObjectType2"
                }
            ] 
        },
        "prop4Array": {
            "type": "array",
            "items": {
                "oneOf": [
                    {
                        "$ref": "#/definitions/propObjectType1"
                    },
                    {
                        "$ref": "#/definitions/propObjectType2"
                    }
                ] 
            }       
        },
        "prop5Array": {
            "type": "array",
            "items": {
                "anyOf": [
                    {
                        "$ref": "#/definitions/propObjectType1"
                    },
                    {
                        "$ref": "#/definitions/propObjectType2"
                    }
                ] 
            }       
        }
    }
}

So in the above definition the prop2 and prop3 are the same (you can use interchangeably anyOf or oneOf) and you can define what ever you are comfortable with. but, in case of array:

  1. when you use anyOf for the items type, the elements can be of any type out of those and the array can contain the mixed items. Means you can have one item of type 1 and another item of type 2.
  2. when you use oneOf for the items type, the elements can be of any type out of those and the array can contain only one type of items. Means all the items must be of the same type (either type 1 or type 2).
Fated answered 8/5, 2019 at 11:33 Comment(0)
R
0

Distinction between anyOf and oneOf:

  • anyOf is a regular OR-combination of JSON sub-schemas.

  • oneOf is an exclusive OR-combination, or an XOR-combination, of JSON sub-schemas.

Recount answered 9/4 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.