3

Is there a way to create a repetition pattern for elements inside array of a JSON Schema document. I would like to use it in order to validate query produced by a query builder tool.

the part of the schema i currently use is

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

This allows me correct validation of query "conditionA && conditionB && conditionC" as

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

However, I would like to be able and validate documents where query is stored as

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

and this to achievable for any number of conditions.

1 Answer 1

2

In order to achieve what you intend to do you would need to define a rule for odd and even positions in an array, which can not be done for arrays of any length with json-schema.

If your expected number of query conditions is not going to grow ad infinitum, you could hard-code the first n positions in items keyword:

"items":[{"$ref":"#/condition},{"$ref":"#/operator"},{"$ref":"#/condition},{"$ref":"#/operator"} ... etc.]

In this case you still have the problem that you could define a wrong condition ending in "operator". Other option would be to make "oneOf" and build each posibility (this could be automated with a script, I guess you won't have expressions with 100 clauses...)

Anyway I find a bit strange to try to flatten a concept that is inherently recursive. How would you store this ( (A OR B) OR (C AND B))?

So If you can still rethink your desired serialization schema format I would suggest you to make a recursive approach. Something like:

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

"clause" : {
    "type" : "array",
    "items" : [{
            "$ref" : "#/condition"
        }
    ],
    "additionalItems" : {
        "type" : "array",
        "items" : [{
                "$ref" : "#/operator"
            }, {
                "$ref" : "#/clause"
            }
        ]
    }
}

The generated string is more ugly, but parsing it would be fairly easy with a simple recursive function:

Simple condition:

[["condition1"]]

Simple Clause:

[["condition1",["OR",["condition2"]]]

Adding a clause at the same level

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

Add a clause to a child level

[["condition1",["OR",["condition2"]],["OR",["condition3", ["AND",["condition4"]]]]]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.