JSON-Schema: "allof" mit "additionalProperties"
Angenommen, wir haben folgenden schema schema (aus tutorial hier):
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
},
"type": "object",
"properties": {
"billing_address": { "$ref": "#/definitions/address" },
"shipping_address": {
"allOf": [
{ "$ref": "#/definitions/address" },
{ "properties":
{ "type": { "enum": [ "residential", "business" ] } },
"required": ["type"]
}
]
}
}
}
Ist hier und gültige Instanz:
{
"shipping_address": {
"street_address": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"type": "business"
}
}
Ich brauche, um sicherzustellen, dass jede zusätzliche Felder für shipping_address
ungültig. Ich weiß, für diesen Zweck existiert additionalProperties
die sollte auf "false" gesetzt. Aber wenn ich die Einstellung "additionalProprties":false
wie im folgenden:
"shipping_address": {
"allOf": [
{ "$ref": "#/definitions/address" },
{ "properties":
{ "type": { "enum": [ "residential", "business" ] } },
"required": ["type"]
}
],
"additionalProperties":false
}
Bekomme ich einen Fehler bei der überprüfung (geprüft hier):
[ {
"level" : "error",
"schema" : {
"loadingURI" : "#",
"pointer" : "/properties/shipping_address"
},
"instance" : {
"pointer" : "/shipping_address"
},
"domain" : "validation",
"keyword" : "additionalProperties",
"message" : "additional properties are not allowed",
"unwanted" : [ "city", "state", "street_address", "type" ]
} ]
Die Frage ist: wie soll ich mich einschränken Felder für die shipping_address
Teil nur? Vielen Dank im Voraus.
InformationsquelleAutor der Frage lm. | 2014-03-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
[Autor des Entwurfs v4 Validierung Skillung hier]
Haben Sie stolperte über die häufigsten Probleme in JSON-Schema, das heißt, seine grundlegende Unfähigkeit, die Vererbung als Benutzer erwarten; aber zur gleichen Zeit ist es eines der Kern-features.
Wenn du dies tust:
schema1
undschema2
haben keine wissen eines anderen; Sie werden ausgewertet, in Ihrem eigenen Kontext.In Ihrem Szenario, die vielen, vielen Menschen begegnen, die Sie erwarten, dass die definierten Eigenschaften in
schema1
bekanntschema2
; aber dies ist nicht der Fall und wird es nie sein.Dieses problem ist der Grund, warum ich diese zwei Vorschläge für den Entwurf von v5:
strictProperties
,merge
.Ihrem schema für
shipping_address
wäre dann:zusammen mit der Definition
strictProperties
zutrue
imaddress
.Ich bin übrigens auch der Autor der website, auf die Sie sich beziehen.
Nun, lassen Sie mich wieder ansetzen zu Entwurf v3. Entwurf v3 hat definieren
extends
, und sein Wert war entweder ein schema oder ein array von schemas. Durch die definition dieses Schlüsselwort, das bedeutete, dass die Instanz musste um gültig zu sein, gegen das aktuelle schema und alle schemas angegeben inextends
; im Grunde Entwurf v4 istallOf
Entwurf v3extends
.Betrachten Sie diese (draft v3):
Und jetzt das:
Sind Sie gleich. Oder vielleicht das?
Oder?
Alles in allem bedeutet dies, dass
extends
im Entwurf v3 nie wirklich getan hat, was Menschen erwartet, es zu tun. Mit dem Entwurf v4*Of
Schlüsselwörter sind klar definiert.Aber das problem, das Sie haben, ist das am häufigsten auftretende problem, bei weitem. Daher meine Vorschläge, die stillen würde diese Quelle von Missverständnissen ein für alle mal!
InformationsquelleAutor der Antwort fge
additionalProperties
gilt für alle Eigenschaften, die nicht berücksichtigt werden durch dieproperties
oderpatternProperties
im unmittelbaren schema.Dies bedeutet, dass, wenn Sie haben:
additionalProperties
hier gilt alle Eigenschaften, denn es gibt keine Geschwister-Ebeneproperties
Eintrag - das innerhalballOf
zählen nicht.Eine Sache, die Sie tun können, ist zu bewegen das
properties
definition eine Ebene höher, und liefern stub-Einträge für die Eigenschaften, die Sie importieren:Dies bedeutet, dass
additionalProperties
gelten nicht für die Eigenschaften, die Sie wollen.InformationsquelleAutor der Antwort cloudfeet
Hier ist eine leicht vereinfachte version von Yves-M-Lösung:
Dadurch bleibt die Validierung der geforderten Eigenschaften in der Basis
address
schema, und fügt nur die benötigtentype
Eigenschaft in dershipping_address
.Es ist bedauerlich, dass
additionalProperties
nimmt nur die unmittelbaren, Geschwister-level-Eigenschaften berücksichtigt. Vielleicht gibt es einen Grund für diese. Aber das ist, warum wir brauchen, um zu wiederholen die vererbten Eigenschaften.Hier, wir wiederholen die vererbten Eigenschaften in vereinfachter form, mit leeren Objekt-syntax. Dies bedeutet, dass Eigenschaften mit diesen Namen würde gültig sein, egal, welche Art von Wert, den Sie enthalten. Aber verlassen wir uns auf die
allOf
Stichwort zu erzwingen, die Typ-Einschränkungen (und andere Einschränkungen) erklärt in der Basisaddress
schema.InformationsquelleAutor der Antwort Ted Epstein
Nicht additionalProperties=false bei der definition der Ebene
Und alles wird gut:
Jede Ihrer
billing_address
undshipping_address
sollten geben Sie Ihre eigenen geforderten Eigenschaften.Ihre definition sollte nicht
"additionalProperties": false
wenn Sie möchten, kombinieren, um seine Eigenschaften mit anderen.InformationsquelleAutor der Antwort Yves M.