数组内部的JSON-Schema模式重复

时间:2014-11-14 10:11:25

标签: json validation jsonschema

有没有办法为JSON Schema文档的数组内的元素创建重复模式。我想使用它来验证查询构建器工具生成的查询。

我目前使用的架构部分是

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

但是,我希望能够并验证查询存储为

的文档
[conditionA,"AND",conditionB,"AND",conditionC]

这可以在任何条件下实现。

1 个答案:

答案 0 :(得分:0)

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

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

“项”:[{ “$ REF”: “#/条件},{” $ REF “:” #/操作员 “},{” $ REF “:” #/条件},{ “$ 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"]]]]]