Existe-t-il un moyen d'activer une propriété de schéma JSON en tant que nombre ou null
?
Je crée une API qui contient un attribut heading
. Il peut s'agir d'un nombre compris entre 0 (inclus) et 360 (exclusif), ou null, de sorte que les entrées suivantes sont correctes:
{"heading": 5}
{"heading": 0}
{"heading": null}
{"heading": 12}
{"heading": 120}
{"heading": null}
Et les entrées suivantes sont erronées:
{"heading": 360}
{"heading": 360.1}
{"heading": -5}
{"heading": false}
{"heading": "X"}
{"heading": 1200}
{"heading": false}
Addendum:
anyOf
est clairement la bonne réponse. Ajout du schéma complet pour plus de clarté.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"heading": {
"anyOf": [
{"type": "number"},
{"type": "null"}
]
}
}
}
Dans le projet-04, vous utiliseriez la directive anyOf:
{
"anyOf": [
{
"type": "number",
"minimum": 0,
"maximum": 360,
"exclusiveMaximum": true
},
{
"type": "null"
}
]
}
Vous pouvez également utiliser "type": ["nombre", "null"] comme le suggère Adam, mais je pense que anyOf est plus propre (tant que vous utilisez une implémentation draft-04), et lie la déclaration minimale et maximale au nombre explicitement.
Avertissement: je ne sais rien de l'implémentation python, ma réponse concerne le schéma json.
L'astuce consiste à utiliser un tableau de types. Au lieu de:
"type": "number"
Utilisation:
"type": ["number", "null"]
Le code suivant applique une stratégie numérique ou nulle, plus des restrictions numériques si la valeur est un nombre:
from jsonschema import validate
from jsonschema.exceptions import ValidationError
import json
schema=json.loads("""{
"$schema": "http://json-schema.org/schema#",
"description": "Schemas for heading: either a number within [0, 360) or null.",
"title": "Tester for number-or-null schema",
"properties": {
"heading": {
"type": ["number", "null"],
"exclusiveMinimum": false,
"exclusiveMaximum": true,
"minimum": 0,
"maximum": 360
}
}
}""")
inputs = [
{"heading":5}, {"heading":0}, {"heading":360}, {"heading":360.1},
{"heading":-5},{"heading":None},{"heading":False},{"heading":"X"},
json.loads('''{"heading":12}'''),json.loads('''{"heading":120}'''),
json.loads('''{"heading":1200}'''),json.loads('''{"heading":false}'''),
json.loads('''{"heading":null}''')
]
for input in inputs:
print "%-30s" % json.dumps(input),
try:
validate(input, schema)
print "OK"
except ValidationError as e:
print e.message
Qui donne:
{"heading": 5} OK
{"heading": 0} OK
{"heading": 360} 360.0 is greater than or equal to the maximum of 360
{"heading": 360.1} 360.1 is greater than or equal to the maximum of 360
{"heading": -5} -5.0 is less than the minimum of 0
{"heading": null} OK
{"heading": false} False is not of type u'number', u'null'
{"heading": "X"} 'X' is not of type u'number', u'null'
{"heading": 12} OK
{"heading": 120} OK
{"heading": 1200} 1200.0 is greater than or equal to the maximum of 360
{"heading": false} False is not of type u'number', u'null'
{"heading": null} OK