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

car*_*mom 3 validation json 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"]
                }

            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑 jsonschema 的确切部分,但其field1元素如下:

"field1": {
    "type": "integer",
    "minimum": 5,
    "maximum": 10,
    "title": "field1"
}
Run Code Online (Sandbox Code Playgroud)
  • 第一个示例仅验证其字段中的大写字母1
  • 第二个需要 5 到 10 之间的整数。

如何才能使其验证其中任何一个,以便两者都被接受 -

  • 要么只有大写字母
  • 或者5 到 10 之间的整数?

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

我尝试过各种想法-用oneOf-这里这里这里

参数-这里

附加属性 -此处

必填 -这里

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

有谁知道如何解决这个问题?我没有主意了..

Jas*_*ers 5

你是一个正确的轨道oneOf,除了你真正想要的是anyOf。几乎每次你认为你想要的时候oneOf,你确实想要anyOf。请记住, 的值与properties其他值一样都是模式。您可以像在其他地方一样使用布尔关键字。

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

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑1

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

{
  "type": "object",
  "properties": {
    "anyOf": [
      {
        "field1": { ... }
      },
      {
        "field1": { ... }
      }
    ],
    "required": { ... },
    "decisive": { ... }
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑2

因为它出现在评论中,所以这里有一个更好的解释为什么oneOf几乎从来都不是正确的选择。需要明确的是,oneOf将始终代替anyOf. 如果anyOf不存在,JSON Schema 也不会失去任何表达能力。

然而,anyOf是一个更精确的工具。使用oneOf“when anyOfwill do”就像在工具箱中有一把简单的羊角锤时使用大锤来钉钉子一样。

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

anyOf意味着任何一项都可能是真的。oneOf意味着其中一项且只有一项为真。当您使用 时oneOf,验证器需要测试所有模式,以确保一个模式验证为 true,其余模式验证为 false。当您使用 时anyOf,验证器可以在找到验证为 true 的模式后立即停止。这称为“短路”,所有现代编程语言在评估 OR 运算时都会这样做。当模式是互斥的(几乎总是如此)时,在找到模式后继续验证模式纯粹是浪费,因此应该避免。

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


归档时间:

查看次数:

875 次

最近记录:

6 年,10 月 前