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

JSON-Schema: Conditional dependency (by value)

这是简化的 JSON-架构:

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

我要实现的是:

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

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

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

你可以用switch keyword from JSON-schema v5/6 proposals that is supported in Ajv表达这个需求(我是作者)

Draft-07 下,您可以通过有条件地应用架构要求来实现:

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

}

这是一个验证它的工作示例:

{
    "account": {
        "type": "COMPANY"
    },
    "person": {
        "firstName": "John",
        "lastName": "Doe"
    },
    "company": {
        "name": "XYZ Corp"
    }
}