/ / JSON-Schema-Musterwiederholung innerhalb des Arrays - json, Validierung, jsonschema

JSON-Schema-Musterwiederholung innerhalb des Arrays - json, validation, jsonschema

Gibt es eine Möglichkeit, ein Wiederholungsmuster für Elemente innerhalb eines Arrays eines JSON-Schemadokuments zu erstellen? Ich möchte es verwenden, um die von einem Abfrageerstellungstool erstellte Abfrage zu validieren.

Der Teil des Schemas, den ich derzeit verwende, ist

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

Dies ermöglicht mir die korrekte Validierung der Abfrage "BedingungA && BedingungB && BedingungC" als

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

Ich möchte jedoch Dokumente validieren können, in denen die Abfrage gespeichert ist

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

und dies für eine beliebige Anzahl von Bedingungen erreichbar.

Antworten:

0 für die Antwort № 1

Um das zu erreichen, was Sie beabsichtigen, müssen Sie eine Regel für ungerade und gerade Positionen definieren in einem Array, was für Arrays beliebiger Länge mit json-schema nicht möglich ist.

Wenn Ihre erwartete Anzahl von Abfragebedingungen nicht unendlich wächst, können Sie die ersten n Positionen im Schlüsselwort items fest codieren:

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

In diesem Fall haben Sie immer noch das Problem, dass Siekönnte eine falsche Bedingung definieren, die mit "operator" endet. Eine andere Möglichkeit wäre, "oneOf" zu machen und jede Möglichkeit zu erstellen (dies könnte mit einem Skript automatisiert werden, ich denke, Sie werden keine Ausdrücke mit 100 Klauseln haben ...)

Auf jeden Fall finde ich es etwas seltsam, ein Konzept zu reduzieren, das von Natur aus rekursiv ist. Wie würden Sie dies speichern ((A ODER B) ODER (C UND B))?

Wenn Sie also Ihr gewünschtes Serialisierungsschema-Format noch überdenken können, würde ich Ihnen empfehlen, einen rekursiven Ansatz zu wählen. Etwas wie:

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

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

Die generierte Zeichenfolge ist hässlicher, aber das Parsen wäre mit einer einfachen rekursiven Funktion ziemlich einfach:

Einfacher Zustand:

[["condition1"]]

Einfache Klausel:

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

Hinzufügen einer Klausel auf derselben Ebene

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

Fügen Sie einer untergeordneten Ebene eine Klausel hinzu

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