web-dev-qa-db-ja.com

JSONスキーマ:数値またはnull値を検証する

JSONスキーマプロパティを数値またはnullのいずれかにする方法はありますか?

heading属性を含むAPIを構築しています。 0(両端を含む)から360(両端を含まない)までの数値、またはnullにすることができるため、次の入力は問題ありません。

{"heading": 5}
{"heading": 0}
{"heading": null}
{"heading": 12}
{"heading": 120}
{"heading": null}

そして、次の入力は誤りです:

{"heading": 360}
{"heading": 360.1}
{"heading": -5}
{"heading": false}
{"heading": "X"}
{"heading": 1200}
{"heading": false}

補遺:

anyOfは明らかに正しい答えです。明確にするために完全なスキーマを追加します。

スキーマ

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "heading": {
        "anyOf": [
          {"type": "number"},
          {"type": "null"}
        ]
      }
    }
}
24
Adam Matan

Draft-04では、anyOfディレクティブを使用します。

{
  "anyOf": [
    {
      "type": "number",
      "minimum": 0,
      "maximum": 360,
      "exclusiveMaximum": true
    },
    {
      "type": "null"
    }
  ]
}

Adamが示唆するように、 "type":["number"、 "null"]を使用することもできますが、anyOfは(draft-04実装を使用する限り)よりクリーンであり、最小と最大の宣言を数値に関連付けます明示的に。

免責事項:python実装については何も知りません。私の答えはjsonスキーマについてです。

37
fiddur

トリックは型配列を使用することです。の代わりに:

"type": "number"

使用する:

"type": ["number", "null"]

次のコードは、数値またはnullのポリシーと、値が数値の場合は数値の制限を適用します。

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

それは与える:

{"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
34
Adam Matan