В чем разница между anyof и oneof в схеме z?

Похоже, оба отлично работают с моим кодом проверки ввода. Тогда в чем точная разница?

Схема с 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"}
   }
 }
]

Схема с 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"}
   }
 }
]

person Somnath    schedule 02.12.2015    source источник
comment
Что говорится в документации? С какой частью этой документации у вас возникли проблемы?   -  person T.J. Crowder    schedule 02.12.2015


Ответы (2)


Если вы посмотрите документацию по схеме JSON, в ней говорится:

5.5.4. любой из

5.5.4.1. Допустимые значения

Значение этого ключевого слова ДОЛЖНО быть массивом. Этот массив ДОЛЖЕН иметь хотя бы один элемент.

Элементы массива ДОЛЖНЫ быть объектами. Каждый объект ДОЛЖЕН быть действующей схемой JSON.

5.5.4.2. Условия успешной валидации

Экземпляр успешно проверяется по этому ключевому слову, если он успешно проверяется по по крайней мере одной схеме, определенной значением этого ключевого слова.

5.5.5. один из

5.5.5.1. Допустимые значения

Значение этого ключевого слова ДОЛЖНО быть массивом. Этот массив ДОЛЖЕН иметь хотя бы один элемент.

Элементы массива ДОЛЖНЫ быть объектами. Каждый объект ДОЛЖЕН быть действующей схемой JSON.

5.5.5.2. Условия успешной валидации

Экземпляр успешно проверяется по этому ключевому слову, если он успешно проверяется на ровно одну схему, определенную значением этого ключевого слова.

Обратите внимание на мой акцент на вышеизложенном. anyOf означает, что элемент должен соответствовать хотя бы одной (но, возможно, более чем одной) схемам. oneOf означает, что он должен проверяться по только одной из схем.

person T.J. Crowder    schedule 02.12.2015
comment
Ха-ха-ха ... хорошо ... это означает .... oneof = писать так много операторов if и else один за другим, а anyof = писать if и elseif ... :) не так ли? - person Somnath; 02.12.2015
comment
@Somnath: У меня проблемы с пониманием этого вопроса, но если я его понимаю, у вас все наоборот. anyOf потребует, чтобы элемент был протестирован по каждой из схем до тех пор, пока он не совпадет хотя бы с одной, а затем более поздние схемы могут быть проигнорированы (не имеет значения, соответствует ли он им или нет). oneOf означает, что элемент необходимо протестировать по каждой схеме даже после того, как он соответствует одной, а если он соответствует другой, тест должен завершиться ошибкой. - person T.J. Crowder; 02.12.2015
comment
Точно. Большое спасибо @ T.J. Краудер - person Somnath; 02.12.2015

Я опаздываю на поиски, но, насколько я понимаю, использование этого ключевого слова зависит от типа самого объекта / родителя. например, если вы пытаетесь определить тип для одного свойства объекта или элемента массива. возьмите пример ниже:

{
    "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"
                    }
                ] 
            }       
        }
    }
}

Итак, в приведенном выше определении prop2 и prop3 одинаковы (вы можете использовать взаимозаменяемо anyOf или oneOf), и вы можете определить то, что вам удобно. но в случае массива:

  1. когда вы используете anyOf для типа элементов, элементы могут быть любого типа из них, а массив может содержать смешанные элементы. Означает, что у вас может быть один предмет типа 1, а другой предмет типа 2.
  2. когда вы используете oneOf для типа элементов, элементы могут быть любого типа из них, а массив может содержать только один тип элементов. Означает, что все элементы должны быть одного типа (либо типа 1, либо типа 2).
person Anant Anand Gupta    schedule 08.05.2019