jsonschema验证所需和/或有条件要求的属性

时间:2017-10-09 14:40:48

标签: properties conditional optional jsonschema required

我需要验证一个总是有2个属性的json对象:

  • 名称

类型可以是“A”,“B”或“C”,

当type为“A”时,属性“foo”也是必需的,不允许使用其他属性。

行:

{
    "type": "A",
    "name": "a",
    "foo": "a",
}

不行:

{
    "type": "A",
    "name": "a",
    "foo": "a",
    "lol": "a"
}

当type为“B”时,属性“bar”是必需的,不允许使用其他属性。

当类型为“C”时,属性“bar”是必需的,并且可选地还可以存在“zen”属性。

行:

{
    "type": "C",
    "name": "a",
    "bar": "a",
    "zen": "a"
}

{
    "type": "C",
    "name": "a",
    "bar": "a",
}

不行:

{
    "type": "C",
    "name": "a",
    "bar": "a",
    "lol": "a" 
}

不幸的是,这个question的优秀答案部分涵盖了我的案例,但是我没有设法建立一个适合我的jsonschema。

编辑:

这是我尝试过的。

{
    "$schema": "http://json-schema.org/draft-04/schema",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "enum": ["A", "B", "C"]
        },
        "name": {"type": "string"},
        "foo": {"type": "string"},
        "bar": {"type": "string"},
        "zen": {"type": "string"},
    },
    "anyOf": [
        {
            "properties": {"type": {"enum": ["A"]}},
            "required": ["foo"],
        },
        {
            "properties": {"type": {"enum": ["B"]}},
            "required": ["bar"],
        },
        {
            "properties": {"type": {"enum": ["C"]}},
            "required": ["bar"],
        },
    ]
}

我的问题是在“anyOf”中的对象内设置字段“additionalProperties”为false并不能给我预期的结果。

例如,以下json传递验证,尽管它具有附加属性“lol”

{
    "type": "A",
    "name": "a",
    "foo": "a",
    "lol": "a"
}

2 个答案:

答案 0 :(得分:1)

以下模式对您的示例有用。希望这对其他人有帮助。技巧是将additionalPropertiesmaxProperties结合使用,并在正确的位置使用required

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": [
        "A",
        "B",
        "C"
      ]
    },
    "name": {
      "type": "string"
    },
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "string"
    },
    "zen": {
      "type": "string"
    }
  },
  "required": [
    "name",
    "type"
  ],
  "allOf": [
    {
      "if": {
        "properties": {
          "type": {
            "const": "A"
          }
        }
      },
      "then": {
        "required": [
          "foo"
        ],
        "maxProperties": 3
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "B"
          }
        }
      },
      "then": {
        "required": [
          "bar"
        ],
        "maxProperties": 3
      }
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "C"
          }
        }
      },
      "then": {
        "required": [
          "bar"
        ],
        "maxProperties": 4
      }
    }
  ],
  "additionalProperties": false
}

答案 1 :(得分:0)

JSON Schema是一个约束系统,其中每个子模式的约束都是单独计算的。这意味着" additionalProperties"只能"看" "属性"或" patternProperties"在同一个直接架构对象中。

此外,它不能"看"基于"必需"的属性,仅限于"属性"和" patternProperties"。

据我所知,如果你在anyOf的每个分支内设置" additionalProperties":false,那么这一切都不应该起作用,因为唯一允许的属性是"类型&#34 ;.如果你这样做并且它允许"键入"以外的属性,那么我想知道你正在使用什么实现。