
本文旨在帮助开发者理解并解决在使用 JSON Schema 验证 JSON 数据时,由于 oneOf 约束可能导致的“无效枚举值”的错误提示问题。我们将通过示例代码,详细解释错误产生的原因,并提供相应的解决方案,以确保 JSON Schema 验证的准确性和可读性。
在使用 JSON Schema 验证 JSON 数据时,oneOf 关键字用于指定数据必须符合多个子模式中的一个。然而,当数据不符合任何一个子模式时,验证器会报告每个子模式的验证失败信息,这可能导致一些“误报”,例如“Value is not defined in enum”。理解这些错误信息背后的原因对于编写健壮的 JSON Schema 至关重要。
问题分析
考虑以下 JSON Schema 和 JSON 数据:
JSON Schema:
{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "eventName": { "type": "string", "enum": ["Test10", "Test12", "Test1", "Test2", "Test3"] }, "eventPayload": { "type": "object", "properties": { "totalAmount": { "type": "number" } } } }, "oneOf": [ { "properties": { "eventName": { "enum": ["Test10", "Test12"] }, "eventPayload": { "properties": { "totalAmount": { "exclusiveMinimum": 0 } } } } }, { "properties": { "eventName": { "enum": ["Test1", "Test2", "Test3"] }, "eventPayload": { "properties": { "totalAmount": { "exclusiveMaximum": 0 } } } } } ]}
JSON Data:
{ "eventName": "Test12", "eventPayload": { "totalAmount": -5 }}
使用此 Schema 验证此 JSON 数据时,可能会得到以下错误:
Find JSON Path Online
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
30 查看详情
Message: Value "Test12" is not defined in enum.Schema path: #/oneOf/1/properties/eventName/enumMessage: Integer -5 is less than minimum value of 0.Schema path: #/oneOf/0/properties/eventPayload/properties/totalAmount/minimum
第一个错误信息 “Value “Test12″ is not defined in enum” 看似不正确,因为 “Test12” 确实在顶级 eventName 的 enum 中定义了。但实际上,这个错误是 oneOf 导致的。 oneOf 中的第二个子模式要求 eventName 必须是 “Test1”, “Test2” 或 “Test3” 之一。由于 “Test12” 不满足这个条件,因此验证器报告了这个错误。 第二个错误信息 “-5 is less than minimum value of 0” 是正确的,因为它违反了 oneOf 中第一个子模式的 exclusiveMinimum 约束。
解决方案
虽然 oneOf 的这种行为是符合规范的,但在实际应用中,我们可能希望只看到最相关的错误信息。解决这个问题的一种方法是重新设计 Schema,避免使用 oneOf,而是使用更精确的约束。
例如,可以将 Schema 修改为:
{ "$schema": "https://json-schema.org/draft/2019-09/schema", "type": "object", "properties": { "eventName": { "type": "string", "enum": ["Test10", "Test12", "Test1", "Test2", "Test3"] }, "eventPayload": { "type": "object", "properties": { "totalAmount": { "type": "number" } } } }, "if": { "properties": { "eventName": { "enum": ["Test10", "Test12"] } } }, "then": { "properties": { "eventPayload": { "properties": { "totalAmount": { "exclusiveMinimum": 0 } } } } }, "else": { "properties": { "eventPayload": { "properties": { "totalAmount": { "exclusiveMaximum": 0 } } } } }}
在这个修改后的 Schema 中,我们使用了 if-then-else 结构来根据 eventName 的值应用不同的约束。如果 eventName 是 “Test10” 或 “Test12″,则 totalAmount 必须大于 0;否则,totalAmount 必须小于 0。 这样,当 eventName 为 “Test12″,而 totalAmount 为 -5 时,只会报告 “Integer -5 is less than minimum value of 0” 这一个错误,避免了不必要的 “Value “Test12″ is not defined in enum” 错误。
注意事项
使用 oneOf 时,要仔细分析验证器返回的错误信息,理解其背后的原因。尽量使用更精确的约束(如 if-then-else)来替代 oneOf,以减少误报,提高 Schema 的可读性和可维护性。选择合适的 JSON Schema 验证器。不同的验证器可能产生不同的错误信息,有些验证器可能提供更详细或更友好的错误提示。
总结
oneOf 是 JSON Schema 中一个强大的关键字,但需要谨慎使用。理解其工作原理以及可能产生的副作用,可以帮助我们编写更健壮、更易于理解的 JSON Schema。 通过重新设计 Schema 结构,例如使用 if-then-else 结构,可以有效地避免由于 oneOf 导致的无效枚举值错误提示,提高 JSON Schema 验证的准确性和效率。
以上就是使用 JSON Schema 中的 oneOf 避免无效枚举值的错误提示的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/211379.html
微信扫一扫
支付宝扫一扫