数组内的JSON模式重复

数组内的JSON模式重复,json,validation,jsonschema,Json,Validation,Jsonschema,有没有一种方法可以为JSON模式文档数组中的元素创建重复模式。我想使用它来验证查询生成器工具生成的查询 我当前使用的模式部分是 "complexCondition": { "anyOf": [ { "title": "Simple condition, e.x. X==0", "type": "string" }, { "type": "array",

有没有一种方法可以为JSON模式文档数组中的元素创建重复模式。我想使用它来验证查询生成器工具生成的查询

我当前使用的模式部分是

"complexCondition": {
    "anyOf": [
        {
            "title": "Simple condition, e.x. X==0",
            "type": "string"
        },
        {
            "type": "array",
            "items": [
                {
                    "$ref": "#/complexCondition"
                },
                {
                    "type": "string", "enum": ["AND","OR"]
                },
                {
                    "$ref": "#/complexCondition"
                }
            ],
            "additionalItems": false
        }
    ]
}
这允许我将查询“conditionA&&conditionB&&conditionC”正确验证为

然而,我希望能够在查询存储为

[conditionA,"AND",conditionB,"AND",conditionC]

这在任何情况下都是可以实现的。

为了实现您想要做的事情,您需要为奇数和偶数位置定义一个规则 在数组中,使用json模式无法对任何长度的数组执行此操作

如果您预期的查询条件数量不会无限增长,您可以硬编码items关键字中的前n个位置:

“items”:[{“$ref”:“#/condition},{“$ref”:“#/operator”},{“$ref”:“#/condition},{“$ref”:“#/operator”}……等等]

在这种情况下,您仍然存在一个问题,即您可能会定义一个以“operator”结尾的错误条件。 另一个选择是生成“oneOf”并构建每个可能性(这可以通过脚本自动实现,我想您不会有包含100个子句的表达式…)

不管怎么说,我觉得试图扁平化一个固有的递归概念有点奇怪。 您将如何存储此((A或B)或(C和B))

因此,如果您仍然可以重新考虑所需的序列化模式格式,我建议您采用递归方法。比如:

"predicate" : {
    "type" : "array",
    "items" : {
        "$ref" : "#/clause"
    }
}

"clause" : {
    "type" : "array",
    "items" : [{
            "$ref" : "#/condition"
        }
    ],
    "additionalItems" : {
        "type" : "array",
        "items" : [{
                "$ref" : "#/operator"
            }, {
                "$ref" : "#/clause"
            }
        ]
    }
}
生成的字符串更难看,但使用简单的递归函数解析它会相当容易:

简单条件:

[["condition1"]]
简单条款:

[["condition1",["OR",["condition2"]]]
在同一级别添加子句

[["condition1",["OR",["condition2"]],["OR",["condition3"]]]
将子句添加到子级

[["condition1",["OR",["condition2"]],["OR",["condition3", ["AND",["condition4"]]]]]
[["condition1",["OR",["condition2"]],["OR",["condition3", ["AND",["condition4"]]]]]