Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python JSON模式:验证数字或空值_Python_Json_Api_Validation_Jsonschema - Fatal编程技术网

Python JSON模式:验证数字或空值

Python JSON模式:验证数字或空值,python,json,api,validation,jsonschema,Python,Json,Api,Validation,Jsonschema,有没有办法使JSON模式属性为数字或null 我正在构建一个包含标题属性的API。可以是介于0(包含)和360(独占)之间的数字,也可以是null,因此以下输入正常: {“标题”:5} {“标题”:0} {“heading”:null} {“标题”:12} {“标题”:120} {“heading”:null} 以下输入错误: {“标题”:360} {“标题”:360.1} {“标题”:-5} {“标题”:false} {“标题”:“X”} {“标题”:1200} {“标题”:false}

有没有办法使JSON模式属性为数字或
null

我正在构建一个包含
标题
属性的API。可以是介于0(包含)和360(独占)之间的数字,也可以是null,因此以下输入正常:

{“标题”:5}
{“标题”:0}
{“heading”:null}
{“标题”:12}
{“标题”:120}
{“heading”:null}
以下输入错误:

{“标题”:360}
{“标题”:360.1}
{“标题”:-5}
{“标题”:false}
{“标题”:“X”}
{“标题”:1200}
{“标题”:false}
附录:

anyOf
显然是正确的答案。为了清晰起见,添加完整的模式

模式
诀窍是使用类型数组。而不是:

"type": "number"
使用:

以下代码强制执行数字或null策略,如果值是数字,则加上数字限制:

来自jsonschema导入验证的

从jsonschema.exceptions导入ValidationError
导入json
schema=json.loads(“”){
“$schema”:”http://json-schema.org/schema#",
“描述”:“标题的模式:介于[0,360]之间的数字或空值。”,
“标题”:“数字或空模式测试仪”,
“财产”:{
“标题”:{
“类型”:[“数字”,“空”],
“排他性最低限额”:错误,
“排他性最大值”:正确,
“最小值”:0,
“最大值”:360
}
}
}""")
输入=[
{“标题”:5},{“标题”:0},{“标题”:360},{“标题”:360.1},
{“标题”:-5},{“标题”:无},{“标题”:假},{“标题”:“X”},
json.loads('''{“heading”:12}''),json.loads(''{“heading”:120}''),
json.loads('''{“heading”:1200}''),json.loads(''{“heading”:false}''),
加载(“”“{”heading:null}“”)
]
对于输入中的输入:
打印“%-30s”%json.dumps(输入),
尝试:
验证(输入、模式)
打印“确定”
除ValidationError为e外:
打印电子邮件
其中:

{“标题”:5}好的
{“标题”:0}好的
{“heading”:360}360.0大于或等于360的最大值
{“heading”:360.1}360.1大于或等于最大值360
{“heading”:-5}-5.0小于最小值0
{“heading”:null}确定
{“heading”:false}false的类型不是u'number',u'null'
{“heading”:“X”}'X'不是类型u'number',u'null'
{“标题”:12}好的
{“标题”:120}好的
{“heading”:1200}1200.0大于或等于360的最大值
{“heading”:false}false的类型不是u'number',u'null'
{“heading”:null}确定

在草稿-04中,您将使用anyOf指令:

{
  "anyOf": [
    {
      "type": "number",
      "minimum": 0,
      "maximum": 360,
      "exclusiveMaximum": true
    },
    {
      "type": "null"
    }
  ]
}
您也可以使用“type”:[“number”,“null”]正如Adam所建议的,但我认为anyOf更干净(只要您使用draft-04实现),并且将最小和最大声明明确地与数字联系起来


免责声明:我对Python的实现一无所知,我的答案是关于JSON模式。

< P>这个答案不考虑JSON模式,但是如果你想在将来考虑一些备选方案,它可能是有用的。 如果您只希望多个可验证元素中的一个成功,可以直接编写:

Validatable<?> validatableElement =
    new OneOf(
        "global",
        new ErrorStub("This field should be either integer, or null, or absent at all"),
        new AsInteger(
            new Required(
                new IndexedValue("header", json)
            )
        ),
        new IsAbsent<>(
            new IndexedValue("header", json)
        )
    );

有关此方法和实现此方法的库的更多信息,请查看更多示例。

不幸的是,2.0规范中似乎不支持
anyOf
:(对于可以使用null作为值的枚举,这如何工作?
{“enum”:[“一”、“二”、“null”]}
似乎不起作用,至少在
jsonschema
的python实现中是如此。请注意
“null”
vs
null
这个六年前的问题被标记为
[python]
,但给定的代码看起来可疑地像
[java]
。哎呀,我的错!不管怎样,python端口就在路上了!
{
  "anyOf": [
    {
      "type": "number",
      "minimum": 0,
      "maximum": 360,
      "exclusiveMaximum": true
    },
    {
      "type": "null"
    }
  ]
}
Validatable<?> validatableElement =
    new OneOf(
        "global",
        new ErrorStub("This field should be either integer, or null, or absent at all"),
        new AsInteger(
            new Required(
                new IndexedValue("header", json)
            )
        ),
        new IsAbsent<>(
            new IndexedValue("header", json)
        )
    );
Result<?> result = validatableElement.result();
assertTrue(result.isSuccessful());
assertEquals(
    24,
    result.value().raw()
);
assertTrue(result.isSuccessful());
assertFalse(result.value().isPresent());