首页 > 解决方案 > Jsonschema:唯一标识元素的数组,有序,与其他有约束的元素一起完成

问题描述

我想为具有这些约束的数据创建一个模式:

->我简化了问题。在实践中,我有超过 2 个对象,以及具有不同约束的“其他对象”放置在数组中的多个位置。

我想到了该oneOf属性,这是我尝试过的:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "Schema01",
    "description": "",
    "type": "array",
    "items": {
        "type": "object",
        "oneOf": [
            {   
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "id": {
                        "const": 1
                    },
                    "val01": {
                        "type": "string"
                    }
                },
                "required": [ "id", "val01" ]
            },
            {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "copy_id": {
                        "const": 4
                    },
                    "val01": {
                        "type": "string"
                    }
                },
                "required": [ "copy_id", "val01" ]
            },
            { 
                "type": "object",
                "additionalProperties": false,
                "properties": {
                    "id": {
                        "const": 2
                    },
                    "val12": {
                        "type": "string"
                    }
                },
                "required": [ "id", "val12" ]
            }

        ]
    }
}

但是这个模式并不能满足我的所有需求。

它正确验证了这些数据样本:->所有必需的对象都在那里(1 和 2),并且有 0 个或更多(这里是 3 个)其他元素满足定义的约束,并放置在 id 1 和 2 之间。

[
    { "id": 1, "val01": "object 1" },
    { "copy_id": 4, "val01": "copy object 1" },
    { "copy_id": 4, "val01": "copy object 2" },
    { "copy_id": 4, "val01": "copy object 3" },
    { "id": 2, "val12": "object 2" }
]

[
    { "id": 1, "val01": "object 1" },
    { "id": 2, "val12": "object 2" }
]

它不验证这些数据样本(这是预期的行为),第一个是因为有一个不允许的属性,最后一个是因为有一个未知元素(id:3):

[
    { "id": 1, "val01": "object 1", "val02": "object 1" },
    { "id": 2, "val12": "object 2" }
]

[
    { "id": 1, "val01": "object 1" },
    { "id": 2, "val12": "object 2" },
    { "id": 3, "val01": "object 1" }
]

但它验证了这三个数据样本,所有样本都应该失效:第一个是因为缺少一个(应该是)必需元素(id:2),第二个是因为其中一个必需元素出现两次(id:2),最后一个是因为顺序不正确(在本例中,copy_id 元素应出现在 id 1 和 id 2 之间)。

[
    { "id": 1, "val01": "object 1" }
]

[
    { "id": 1, "val01": "object 1" },
    { "id": 2, "val12": "object 2" },
    { "id": 2, "val12": "object 44" }
]

[
    { "id": 1, "val01": "object 1" },
    { "id": 2, "val12": "object 2" },
    { "copy_id": 4, "val01": "copy object 1" },
    { "copy_id": 4, "val01": "copy object 2" },
    { "copy_id": 4, "val01": "copy object 3" }
]

所以(至少?)缺少三个约束:

有可能做我正在尝试的事情吗?或者也许那个 json-schema 不能在这个时候做这种事情?

一种选择是在验证之前编辑数据,用一个对象替换主数组,其中 id 是键,每个对象的其余部分是值。但我会放松元素的顺序。

如果有可能找到解决第一个缺失约束而不是第三个约束的解决方案(并且不需要编辑数据),我也会很高兴。提前致谢 !

标签: jsonjsonschema

解决方案


所以(至少?)缺少三个约束:

  • 必需元素之一(id 1 或 id 2)不能出现两次;
  • 每个必需的元素(id 1 或 id 2)都应该出现在数据中;
  • 元素的顺序应该很重要。

好的,让我们一次一个地处理每个要求...

必需元素之一(id 1 或 id 2)不能出现两次;

有一个 JSON Schema 关键字uniqueItems,但它只将数组中的每个元素视为一个整体。您无法使用 JSON Schema 进行此类数据完整性检查。

每个必需的元素(id 1 或 id 2)都应该出现在数据中;

这可以做到,但我怀疑你的要求比它看起来的要多。您真的要检查数组是否至少包含一个 id 的对象1和另一个具有2(那些特定值)的对象?或者您的需求是否比自然界更具动态性?(请发表评论,我很乐意提供进一步的帮助。)

元素的顺序应该很重要。

如果您希望第一个元素的 id 为1,第二个元素的 id 为2,这是可能的,但看起来您要求允许其他对象出现在两者之间,这是无法验证的。

JSON Schema 旨在验证 JSON 的结构和格式。听起来您的要求与业务逻辑/应用程序逻辑有关,JSON Schema 通常不包括在内。这极不可能改变,因此您需要编写代码来检查这些类型的业务逻辑需求。


推荐阅读