我正在使用此架构,希望有基于值的条件架构。
如果 app_name 是“测试”,则属性 name 是必需的。
如果 app_name (如果“休息”),则需要属性 ips 。
{
"type": "object",
"oneOf": [
{
"properties": {
"app_name": {"enum": ["test"]}
},
"required": ["name"]
},
{
"properties": {
"app_name": {"enum": ["rest"]}
},
"required": ["ips"]
},
],
"properties": {
"name": {"type": "string"},
"ips": {
"type": "array",
"minItems": 1,
"uniqueItems": True,
"items": {
"type": "string",
"pattern": "[^ ]",
"minLength": 1,
"maxLength": 50
}
},
"app_name": {
"type": "string",
"minLength": 1,
"maxLength": 10,
"enum": [
"test",
"rest"
]
}
},
"required": [
"app_name"
]
}
我正在使用以下代码
formatted_data = {"app_name": "rest", "name": "test data"}
print jsonschema.exceptions.best_match(jsonschema.Draft4Validator(schema).iter_errors(formatted_data))
我收到以下验证错误
“休息”不是['test']之一
无法验证架构[0] ['properties'] ['app_name']中的“枚举”: {'enum':['test']}
在instance ['app_name']上: “休息”
我不确定模式本身是否无效,或者如果self是库问题。
我正在使用
python 2.7
jsonschema 2.6.0
答案 0 :(得分:1)
好吧,似乎架构中有错字。 “ T rue”而不是“ t rue”。
您已经:
"uniqueItems": True,
据我所知,它应该是(尽管它仍然可能取决于模式验证器的实现)
"uniqueItems": true,
(请参阅:http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf第5节JSON值,一般来说是https://www.json.org/-JSON Schema是一个JSON文档,符合JSON标准)
我已经通过https://www.jsonschemavalidator.net/上的.net在线JSON模式验证器运行它,它立即指出上述模式可能存在的错误。
经过错字校正后,按照您在2018年11月16日的评论,它似乎可以完美运行:
当我在app_name中传递值“ rest”时。我期待一个错误 消息“ ips”字段为必填字段。 – Sachin Aryal
完整模式(请注意“示例”部分-仅最后两个示例将针对模式成功验证):
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"anyOf": [
{
"properties": {
"app_name": {"enum": ["test"]}
},
"required": ["name"]
},
{
"properties": {
"app_name": {"enum": ["rest"]}
},
"required": ["ips"]
},
],
"properties": {
"name": {"type": "string"},
"ips": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"pattern": "[^ ]",
"minLength": 1,
"maxLength": 50
}
},
"app_name": {
"type": "string",
"minLength": 1,
"maxLength": 10,
"enum": [
"test",
"rest"
]
}
},
"required": [
"app_name"
],
"examples" : [
{
"app_name" : "rest",
},
{
"app_name" : "test",
},
{
"app_name" : "test",
"ips" : [
"something1",
"something2"
]
},
{
"app_name" : "rest",
"name" : "qwerty"
},
{
"app_name" : "test",
"name" : "qwerty"
},
{
"app_name" : "rest",
"ips" : [
"something1",
"something2"
]
}
]
}
您可以更正模式中的项目并尝试使用您的工具,让我们知道结果吗?
最重要的是:
如果您通过以下验证JSON对象:
{
"app_name" : "rest",
"name" : "qwerty"
},
针对使用“ oneOf”的架构,验证器将/应该针对“ oneOf”数组中的所有架构运行对象,以确保其与提供的架构之一完全匹配。因此,“ oneOf / 0 /”架构的错误是有效的-“ app_name”:“ rest” 不会针对定义的枚举进行验证。验证程序不知道您提供特定的JSON来针对架构进行验证的含义,因此,如果不满足“ allOf”(逻辑XOR)条件,则我希望所有架构的错误都会在“ oneOf”数组中针对JSON运行(即使这些对您来说都是假阳性)。
如果缺少某些错误消息,您可能要考虑与/向lib作者检查并报告您的确切情况。
希望有帮助。
所以看来您是另一个追逐有意义的错误的人;-)是的,使用逻辑运算符时可能会很痛苦。
对于像上面这样的简单情况,您可以使用草案07的 if-then-else 方法,但是需要注意的是-请参阅“备注”。
首先使用架构(请注意如何用两个“ if-then”替换“ anyOf”):
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"if": {
"properties": {
"app_name": {"enum": ["test"]}
},
},
"then" : { "required": ["name"] },
"if" : {
"properties": {
"app_name": {"enum": ["rest"]}
},
},
"then" : { "required": ["ips"]},
"properties": {
"name": {"type": "string"},
"ips": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"pattern": "[^ ]",
"minLength": 1,
"maxLength": 50
}
},
"app_name": {
"type": "string",
"minLength": 1,
"maxLength": 10,
"enum": [
"test",
"rest"
]
}
},
"required": [
"app_name"
],
"examples" : [
{
"app_name" : "rest",
},
{
"app_name" : "test",
},
{
"app_name" : "test",
"ips" : [
"something1",
"something2"
]
},
{
"app_name" : "rest",
"name" : "qwerty"
},
{
"app_name" : "test",
"name" : "qwerty"
},
{
"app_name" : "rest",
"ips" : [
"something1",
"something2"
]
}
]
}
备注
当“ then”和“ else”中的模式不包含嵌套的“ if-then”并且由单个语句/模式表达式组成时,在简单情况下,模式验证器jsonschema.net倾向于提供准确的if-then-else错误。但是,每当构造更复杂的案例时,您可能会遇到一般错误消息,例如: JSON与'then'中的架构不匹配。或 JSON与'else'中的架构不匹配。 (没有其他详细信息)(您需要自己检查python输出)。您可以通过适当地调整依赖项或子模式来解决该问题,但是对于真正复杂的架构,如果您追究详细的错误消息,则无论如何您可能会面临验证程序实现错误消息的限制。请在此处另请参见替代方案2作为示例:https://stackoverflow.com/a/53320222/2811843(重点在于以某种方式构造方案,即if-then-else在单个关键字方案上失败,而方案逻辑的其余部分位于其他关键字下) )
话虽如此,您始终可以使用工具检查该方法,并在必要时向您最喜欢的lib作者提交有关失败的if-then-else模式错误消息详细信息的报告。
带有“依赖项”的替代方式
针对您的情况的另一种选择是使用draft-06中的“ dependencies”关键字,反转初始逻辑并调整“ definitions”节点的形状,这样直接导致唯一错误:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"ips": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"pattern": "[^ ]",
"minLength": 1,
"maxLength": 50
}
},
"app_name": {
"type": "string",
"minLength": 1,
"maxLength": 10,
"enum": [
"test",
"rest"
]
}
},
"required": [
"app_name"
],
"dependencies" : {
"ips" : {
"properties": {
"app_name": {"$ref":"#/definitions/allowed-app_name-value/rest"}
},
},
"name" : {
"properties": {
"app_name": {"$ref":"#/definitions/allowed-app_name-value/test"}
},
}
},
"definitions" : {
"allowed-app_name-value" : {
"test" : {
"enum": ["test"]
},
"rest" : {
"enum": ["rest"]
}
}
},
"examples" : [
{
"app_name" : "rest",
},
{
"app_name" : "test",
},
{
"app_name" : "test",
"ips" : [
"something1",
"something2"
]
},
{
"app_name" : "rest",
"name" : "qwerty"
},
{
"app_name" : "test",
"name" : "qwerty"
},
{
"app_name" : "rest",
"ips" : [
"something1",
"something2"
]
}
]
}
然而,它仍然是一种命名解决方案,旨在以人类可读的方式识别确切的错误。例如,jsonschema .net将为您提供JSON行号和消息,如此处记录的https://www.newtonsoft.com/jsonschema/help/html/JTokenIsValidWithValidationErrors.htm
每个工具都有其自己的错误消息传递方法。请检查github上的JSON Schema团队,因为正在为下一个草案进行统一JSON Schema验证的输出工作。
每当以编程方式分析错误时,如果出现错误索引(方案通常嵌套在模式中),您可能要注意它们,错误发生在哪一行等。