首页 > 解决方案 > jsonSchema 来验证有条件需要的属性

问题描述

我的 JSON 有效负载包含两个属性home_numberhome_name并且始终需要至少一个属性。除此之外,这些属性还具有以下附加约束。

home_number:类型:字符串,最大长度:4

home_name:类型:字符串,最大长度:50

如果两个属性都不满足要求, JSON 模式应该抛出一个错误。

例如:

有效的 JSON

{
    "home_number": "1234", // valid
}

有效的 JSON

{
    "home_number": null, // invalid
    "home_name": "test_home_name" // valid
}

无效的 JSON

{
    "home_number": "12345", // invalid
    "home_name": null // invalid
}

我使用if, then关键字尝试了以下带有draft-07版本的 JSON 模式。

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "address": {
            "$ref": "#/definitions/address",
            "properties": {
                "house_number": {
                    "$ref": "#/definitions/address/house_number"
                },
                "house_name": {
                    "$ref": "#/definitions/address/house_name"
                },
                "post_code": {
                    "$ref": "#/definitions/address/postcode"
                }
            }
        }
    },
    "required": [
        "address"
    ],
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "postcode": {
                    "type": "string",
                    "maxLength": 6
                }
            },
            "anyOf": [
                {
                    "required": [
                        "house_number"
                    ]
                },
                {
                    "required": [
                        "house_name"
                    ]
                }
            ],
            "if": {
                "properties": {
                    "house_name": {
                        "not": {
                            "type": "string",
                            "maxLength": 50
                        }
                    }
                }
            },
            "then": {
                "properties": {
                    "house_number": {
                        "type": "string",
                        "maxLength": 4
                    }
                }
            },
            "required": [
                "postcode"
            ]
        }
    }
}

我的问题是有没有其他/更好的方法来实现这个使用draft-04版本而不使用draft-07if then 关键字?

标签: javajsonjsonschema

解决方案


正如评论中所指出的,这可能已被多次询问。

逻辑运算符的使用完成了下面的技巧、模式和 json 示例。我不能说它是否更好,它只是将“anyOf”中的任何内容分组(以及您可以在需要时添加的邮政编码要求,并且您可以根据需要构建对完整“属性”内部的引用等等。 .)。或者您可以将其称为严格的 XOR "oneOf"(也如注释中所述),并确保每个案例的地址-> 属性定义都按照您的需要进行调整。

请阅读(链接到我自己过去的答案并不优雅,但它可能会引导您进一步阅读):JSON Schema conditional: require and not require

您的问题的简化模式和示例(据我了解):

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties" : {
    "address": {
      "type" : "object",
      "anyOf" : [
        { 
          "properties" : {
            "house_number" : {
              "type":"string",
              "maxLength": 4
            },
          },
          "required":["house_number"]
        },
        { 
          properties : {
            "house_name" : {
              "type" : "string",
                "maxLength" : 50
            }
          },
          "required":["house_name"]
        }
      ]
    }
  },
  required: ["address"],
  examples : [
    {
      baddress: {
      }
    },
    {
      address: {
        "house_number":"1234",
        "house_name" : null
      }
    },
    {
      address: {
        "house_number":null,
        "house_name" : null
      }
    },
    {
      address: {
        "house_number":null,
        "house_name" : "some name"
      }
    },
    {
      address: {
        "house_number": "12345",
        "house_name" : "some afafafasagagagffgfsagragsgasgasssssssfdgsdfgsdfgdsgsdfgsdgsdfgdfsgsdfgs name"
      }
    },
  ]
}

推荐阅读