z 模式中的“anyof”和“oneof”有什么区别?

问题描述 投票:0回答:3

看起来两者都可以很好地处理我的输入验证代码。那么具体的区别是什么呢?

具有 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"}
   }
 }
]

具有任意

的架构
    [{
  "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"}
   }
 }
]
json validation jsonschema json-schema-validator
3个回答
35
投票

如果你查看 JSON Schema 文档,它会说:

anyOf

...

如果实例符合此关键字,则实例验证成功 针对由此定义的至少一个模式成功验证 关键字的值。请注意,在收集注释时,所有 必须检查子模式,以便从以下位置收集注释 每个验证成功的子模式。

oneOf

...

如果实例符合此关键字,则实例验证成功 针对由此定义的恰好一个模式成功验证 关键字的值。

请注意我在上面的强调。

anyOf
表示该项目必须针对至少一个(但可能多个)模式进行验证。
oneOf
意味着它必须针对仅一个 模式进行验证。


8
投票

我在探索中迟到了,但根据我的理解,此关键字的使用取决于对象/父对象本身的类型。例如,如果您尝试定义对象的单个属性或数组的元素的类型。以下面的例子为例:

{
    "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)。

0
投票

anyOf
orOf
之间的区别:

  • anyOf
    是 JSON 子模式的常规
    OR
    组合。

  • oneOf
    是 JSON 子模式的独占
    OR
    组合或
    XOR
    组合。

© www.soinside.com 2019 - 2024. All rights reserved.