【问题标题】:JSON-Schema: Conditional dependency (by value)JSON-Schema:条件依赖(按值)
【发布时间】:2016-11-08 01:49:34
【问题描述】:

这是简化的 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"]
}

我想要实现的是:

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

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

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

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

【问题讨论】:

  • 您使用什么语言?是 JavaScript 吗?
  • JS 但语言无关紧要。这需要在 JSON 模式中完成,而不是在 JS 代码中。

标签: json dependencies jsonschema


【解决方案1】:

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

【讨论】:

  • 我已经在使用 Ajv,这是目前最好的验证器。我将启用v5:true 并尝试switch 关键字。谢谢。
  • 是否可以根据另一个字段的值更改字段的架构?例如,如果“a”为“TRUE”,则“b”必须为“FOO”,否则为“FOO 或 BOO”
  • 你的链接中没有switch关键字了。
【解决方案2】:

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"
    }
}

【讨论】:

    猜你喜欢
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2019-10-18
    相关资源
    最近更新 更多