我有一个JSON和一个JSON模式
JSON:
{
"aaa": "4000-02-01 00:00:00"
}
JSON-架构:
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"aaa": {
"type": "string",
"format": "date-time"
}
}, "required": ["aaa"]
}
JSON由JSON模式验证。但是,如果我将字段aaa
更改为“bla”,则架构不会再注意到它不是日期时间。
我是否遗漏了架构中的任何内容?
答案 0 :(得分:29)
对于Python的jsonschema库,请在调用validate
时指定格式检查器:
jsonschema.validate(data, schema, format_checker=jsonschema.FormatChecker())
要验证日期时间格式,应安装strict-rfc3339包。
答案 1 :(得分:9)
使用"format"
进行验证是可选的。这部分是因为允许模式作者完全构成新格式,因此期望验证所有格式是不合理的。
您的库应(如果它是正确的)有办法为特定格式注册自定义验证器。例如,tv4
验证库(在JavaScript中)具有tv4.addFormat()
method:
tv4.addFormat('date-time', function (data) {
return isValidDate(data);
});
完成此操作后,架构中的"format": "date-time"
应正确验证日期。
答案 2 :(得分:4)
您正在使用的JSON模式验证的实现很可能需要日期和时间组件之间的T
分隔符。这是它所基于的RFC3339规范和ISO8601的主要内容。虽然两者都有省略T
的规定,但它们都可以通过协议来实现,而不是强制要求支持。 (去图。)
此外,RFC3339 要求您包含时区偏移量或Z
以指示UTC。这将其锁定到特定时刻,而不是在某个未知时区中人为代表。由于您既不需要,也可能验证失败。
<强> 7.3.1.2。验证强>
如果字符串实例是 RFC 3339,第5.6节 [RFC3339]定义的有效日期表示,则该字符串实例对此属性有效。
答案 3 :(得分:2)
我使用this library找到了解决方法。它在javascript代码中检查字段的内容:
function isValidDate(datestring) {
var format = d3.time.format("%Y-%m-%d %H:%M:%S");
var date = format.parse(datestring);
if (date) {
return true;
}
return false;
}
答案 4 :(得分:0)
在此示例中,如果将"aaa"
更改为"bla"
,则将添加未定义的新属性,因此架构将仅验证"aaa"
。如果您不想添加属性,我相信您应该添加"additionalProperties": false
。下面的示例:
此处,架构指出"aaa"
是唯一的属性,其值应为日期时间。
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"additionalProperties": false,
"properties": {
"aaa": {
"type": "string",
"format": "date-time"
}
}, "required": ["aaa"]
}
答案 5 :(得分:-1)
您可以更改python jsonschema模块的源代码。
在jsonschema/_format.py
func is_date_time(instance)
找到与日期时间相关的代码。像这样,关于版本2.6.0的第204-225行:
try:
import strict_rfc3339
except ImportError:
try:
import isodate
except ImportError:
pass
else:
@_checks_drafts("date-time", raises=(ValueError, isodate.ISO8601Error))
def is_datetime(instance):
if not isinstance(instance, str_types):
return True
return isodate.parse_datetime(instance)
else:
@_checks_drafts("date-time")
def is_datetime(instance):
if not isinstance(instance, str_types):
return True
return strict_rfc3339.validate_rfc3339(instance)
注释掉上面的内容并将其粘贴,或者将上面的_check_drafts
函数替换为:
@_checks_drafts("date-time")
def is_datetime(instance):
if not isinstance(instance, str_types):
return True
try:
datetime.datetime.strptime(instance, "%Y-%m-%d %H:%M:%S")
except ValueError:
return False
return True