验证jsonchema中的2种可能的数据类型

时间:2018-11-07 17:07:53

标签: json validation jsonschema

我已经花费了一整天的时间来尝试使它生效,并将发布问题后我尝试过的参考文献和内容清单。

这是我的jsonschema:

{
    "data": [{
        "required": "effort",
        "decisive": "maybe",
        "field1": 7
    },
    {
        "required": "effort",
        "decisive": "no",
        "field1": 6
    }],
    "schema": {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
                "field1": {
                    "type": "string",
                    "pattern": "[A-Z]",
                    "title": "field1"
                },
                "required": {
                    "type": "string",
                    "title": "required",
                    "readonly": true
                },
                "decisive": {
                    "type": "string",
                    "title": "Decisive",
                    "enum": ["yes", "no", "maybe", "not now"]
                }

            }
        }
    }
}

考虑jsonschema的确切部分,但使用field1元素,如下所示:

"field1": {
    "type": "integer",
    "minimum": 5,
    "maximum": 10,
    "title": "field1"
}
  • 第一个示例仅验证其field1中的大写字母
  • 第二个想要5到10之间的整数。

您如何使它验证其中一个,所以都被接受-

  • 两个仅大写字母
  • 还是 5到10之间的整数?

哦-上面数据部分中的field1并不是那么重要,它是所需的默认值。

我尝试了各种想法- 与oneOf-hereherehere

param-here

additionalProperties-here

必填-here

直观的方法是在模式上使用oneOf,但是正如许多问题中提到的,oneOf在属性部分内部不执行任何操作,仅在属性部分之外执行任何操作。因此,我试图在oneOf中具有完全相同的属性,但如上所述只有一个不同。那也不起作用,并且包含很多重复,必须以某种方式避免。

有人知道如何解决吗?没主意了。

1 个答案:

答案 0 :(得分:3)

oneOf是您正确的选择,除了您真正想要的是anyOf。几乎每当您认为自己想要oneOf时,您都会真正想要anyOf。请记住,properties的值与其他任何模式一样都是架构。您可以在其他任何地方使用boolean关键字。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "field1": {
                "title": "field1"
                "anyOf": [
                    {
                        "type": "string",
                        "pattern": "[A-Z]"
                    },
                    {
                        "type": "integer",
                        "minimum": 5,
                        "maximum": 10
                    }
                ]
            },
            "required": {
                "type": "string",
                "title": "required",
                "readonly": true
            },
            "decisive": {
                "type": "string",
                "title": "Decisive",
                "enum": ["yes", "no", "maybe", "not now"]
            }

        }
    }
}

编辑1

当您听到oneOf不能在属性内使用时,这就是他们在谈论的事情。

{
  "type": "object",
  "properties": {
    "anyOf": [
      {
        "field1": { ... }
      },
      {
        "field1": { ... }
      }
    ],
    "required": { ... },
    "decisive": { ... }
  }
}

编辑2

由于它出现在注释中,因此可以更好地解释为什么oneOf几乎永远不是正确的选择。需要明确的是,oneOf将始终代替anyOf。如果anyOf不存在,那么JSON Schema不会失去任何表达能力。

但是,anyOf是更精确的工具。在oneOf可用时使用anyOf就像在工具箱中装有简单的羊角锤时使用大锤钉钉子。

anyOf是布尔OR运算。 oneOf是布尔“异或”(XOR)操作。 “ XOR”的用处很小,以至于现代语言甚至都不支持它。 OR通常用运算符||表示。 XOR没有类似物。

anyOf表示任何项都可以为真。 oneOf表示一个,只有一个是正确的。当您使用oneOf时,验证器需要测试所有模式,以确保一个模式验证为true,其余模式验证为false。当您使用anyOf时,验证程序可以在发现验证为true的架构时立即停止。这称为“短路”,所有现代编程语言都在评估“或”运算时执行此操作。如果架构是互斥的(几乎总是如此),则在发现架构后继续验证架构纯属浪费,因此应避免。

我认为oneOf被滥用了,因为从自然语言的角度来看,它听起来是正确的。