JSON-Schema:条件依赖(按值)

时间:2016-11-08 01:49:34

标签: json dependencies jsonschema

这是简化的JSON-Schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "user",
    "type": "object",
    "properties": {
        "account": {
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": ["COMPANY", "PERSON"]
                }
            },
            "required": ["type"]
        },
        "person": {
            "type": "object",
            "properties": {
                "firstName": { "type": "string" },
                "lastName": { "type": "string" }
            },
            "required": ["firstName", "lastName"]
        },
        "company": {
            "type": "object",
            "properties": {
                "name": { "type": "string" },
                "taxNumber": { "type": "string" }
            }
        }
    },
    "required": ["account", "person"]
}

我想要实现的目标是:

  • 如果account.type设置为"COMPANY"
    • company对象及其属性应必需
  • 如果account.type设置为"PERSON"
    • company 对象可选
    • 但如果company对象存在,则company.namecompany.taxNumber必需

这可以通过在oneOf下定义两个长子模式来实现,但这意味着过多的重复项和复杂模式,因为accountcompany具有的属性比这个简化版本。

AFAIK,在架构中定义特定值的唯一方法是将enum关键字与单个项目一起使用。我使用dependencies关键字尝试了此操作,但没有帮助。

你能想到一种不改变数据对象结构的方法吗?

2 个答案:

答案 0 :(得分:3)

您可以使用switch(我是作者)支持的JSON-schema v5 / 6提案中的Ajv关键字来表达此要求。

答案 1 :(得分:0)

草案07 下,您可以通过有条件地应用架构要求来做到这一点:

@Bean
public EhCacheBasedAclCache aclCache() {
    return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(),
            permissionGrantingStrategy(), aclAuthorizationStrategy());
}

下面是一个可以验证其效果的示例:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "id": "user",
    "type": "object",
    "properties": {
        "account": {
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "enum": ["COMPANY", "PERSON"]
                }
            },
            "required": ["type"]
        },
        "person": {
            "type": "object",
            "properties": {
                "firstName": {
                    "type": "string"
                },
                "lastName": {
                    "type": "string"
                }
            },
            "required": ["firstName", "lastName"]
        },
        "company": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                },
                "taxNumber": {
                    "type": "string"
                }
            }
        }
    },
    "if": {
        "properties": {
            "account": {
                "const": {
                    "type": "COMPANY"
                }
            }
        }
    },
    "then": {
        "required": ["account", "person", "company"]
    },
    "else": {
        "required": ["account", "person"]
    }

}