使用 JSON Schema 中的 oneOf 避免无效枚举值的错误提示

使用 json schema 中的 oneof 避免无效枚举值的错误提示

本文旨在帮助开发者理解并解决在使用 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 Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 30 查看详情 Find JSON Path Online

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
疑似魅族 22 真机曝光 后置方形镜头模组 这颜值打几分?
上一篇 2025年11月3日 12:54:02
DeepSeek部署在云服务器时要注意什么 部署环境配置及安全策略建议
下一篇 2025年11月3日 12:54:03

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    100
  • HTML5网页如何实现手势操作 HTML5网页移动端交互的处理技巧

    首先利用原生touch事件实现滑动判断,再通过preventDefault解决滚动冲突,接着引入Hammer.js处理复杂手势,最后通过优化点击区域、避免事件冲突和增加视觉反馈提升体验。 在移动端浏览器中,HTML5网页可以通过触摸事件实现手势操作,提升用户体验。虽然原生JavaScript提供了基…

    2026年5月10日
    000
  • 深入理解 Express.js 中 next() 参数的作用与中间件机制

    本文深入探讨 express.js 中间件函数中的 `next()` 参数。它负责将控制权传递给请求-响应周期中的下一个中间件或路由处理程序。文章将详细解释 `next()` 的工作原理、中间件的注册与执行顺序,以及不正确使用 `next()` 可能导致请求挂起的风险,并通过代码示例和实际应用场景,…

    2026年5月10日
    000
  • JavaScript 动态菜单点击高亮效果实现教程

    本教程详细介绍了如何使用 JavaScript 实现动态菜单的点击高亮功能。通过事件委托和状态管理,当用户点击菜单项时,被点击项会高亮显示(绿色),同时其他菜单项恢复默认样式(白色)。这种方法避免了不必要的DOM操作,提高了性能和代码可维护性,确保了无论点击方向如何,功能都能稳定运行。 动态菜单高亮…

    2026年5月10日
    200
  • JavaScript函数中插入加载动画(Spinner)的正确方法

    本文旨在解决在JavaScript函数中插入加载动画(Spinner)时遇到的异步问题。通过引入async/await和Promise.all,确保在数据处理完成前后正确显示和隐藏加载动画,提升用户体验。我们将提供两种实现方案,并详细解释其原理和优势。 在Web开发中,当执行耗时操作时,显示加载动画…

    2026年5月10日
    000
  • Golang空接口如何应用在项目中

    空接口可用于接收任意类型值,常见于日志函数、通用数据结构、JSON动态解析及配置驱动逻辑,提升代码灵活性,但需配合类型断言确保安全,避免滥用以降低维护成本。 空接口 interface{} 在 Go 语言中是一个非常灵活的类型,它可以存储任何类型的值。虽然它牺牲了一部分类型安全,但在实际项目中合理使…

    2026年5月10日
    100
  • Golang使用Protobuf定义接口与消息格式

    Protobuf通过字段编号实现兼容性,新增字段可忽略、删除字段可保留编号,确保新旧版本互操作,支持服务独立演进。 在Golang项目中,利用Protobuf定义接口和消息格式,本质上是为服务间通信构建了一套高效、类型安全且跨语言的契约。它让数据结构清晰可见,RPC调用标准化,极大地简化了分布式系统…

    2026年5月10日
    000
  • Go语言接口与切片:如何识别和操作[]interface{}

    本文将深入探讨Go语言中如何识别和操作`[]interface{}`类型的切片。我们将介绍类型断言(Type Assertion)的关键作用,并通过`switch`语句演示如何安全地检测`[]interface{}`类型,并进而遍历其内部元素。文章旨在提供清晰的示例代码和专业指导,帮助开发者有效地处…

    2026年5月10日
    000
  • JavaScript计算器开发:解决数值显示与初始化问题

    本教程深入探讨了使用JavaScript构建计算器时常见的数值显示异常问题,特别是由于类属性未初始化导致的`Cannot read properties of undefined`错误。我们将详细分析问题根源,并通过在构造函数中调用初始化方法来解决该问题,同时优化显示逻辑,确保计算器功能稳定且界面显…

    2026年5月10日
    000
  • 从 JavaScript 获取 URL 并在 PHP DataGrid 中使用

    本文档旨在指导开发者如何从 JavaScript 函数中获取 URL,并将其动态应用于 PHP DataGrid。通过前端 JavaScript 动态生成 API 地址,并将其传递给后端的 PHP DataGrid,实现数据根据用户会话动态加载。 动态配置 DataGrid 的 URL 在构建动态 …

    2026年5月10日
    000
  • GolangWeb项目异常捕获与日志记录

    答案:通过中间件使用defer和recover捕获panic,结合zap等结构化日志库记录请求链路信息,为每个请求生成trace ID,实现异常捕获与可追踪日志,提升系统稳定性与可观测性。 在Go语言Web项目中,异常捕获与日志记录是保障系统稳定性和可维护性的关键环节。Go本身没有像其他语言那样的t…

    2026年5月10日
    000
  • HTML5代码如何制作3D效果 HTML5代码中WebGL的入门实例

    最核心的技术是WebGL,通过HTML5的canvas结合JavaScript使用WebGL API渲染3D图形。首先创建包含canvas的HTML页面,获取WebGL上下文,编写GLSL着色器定义顶点位置与颜色,编译着色器并链接成程序,接着设置顶点缓冲区传入三角形坐标和颜色数据,引入gl-matr…

    2026年5月10日
    000
  • HTTP客户端请求缓存与重用优化

    合理使用客户端缓存与连接复用可显著提升Web性能。通过Cache-Control、ETag和Last-Modified实现条件请求,避免重复传输;启用Keep-Alive并维护TCP连接池以减少握手开销;优先采用HTTP/2或HTTP/3实现多路复用与低延迟连接;针对静态资源设置长缓存,动态数据使用…

    2026年5月10日
    000
  • HTML中如何实现MathML

    答案是利用HTML5原生支持MathML,只需将MathML代码嵌入标签即可,现代浏览器能直接渲染,无需插件;通过CSS可美化公式样式,如字体、颜色、间距等,提升显示效果;对于老旧浏览器,推荐使用MathJax作为兼容方案,支持LaTeX输入并渲染为高质量公式,兼顾可访问性与跨浏览器兼容性。 在HT…

    2026年5月10日
    000
  • JavaScript Electron桌面应用

    答案:使用JavaScript开发%ignore_a_1%桌面应用需结合Web技术与Node.js,通过主进程管理窗口、渲染进程展示界面,并利用IPC通信,调用系统功能如文件对话框,最后用electron-builder打包发布,注意安全与进程职责分离。 用JavaScript开发Electron桌…

    2026年5月10日
    000
  • p5.js图像像素化与阈值处理:loadPixels()函数深度解析与性能优化

    本教程深入探讨p5.js中`loadpixels()`函数在图像像素化与阈值处理中的应用。我们将重点讲解如何优化`loadpixels()`的调用时机以提升性能,正确计算图像亮度,并构建清晰有效的条件阈值逻辑。文章还涵盖了避免变量命名冲突、选择合适的绘图函数等关键实践,旨在帮助开发者高效、准确地实现…

    2026年5月10日
    000
  • Python代码如何实现定时任务 Python代码使用Schedule模块的配置

    答案:使用Python的schedule模块可实现定时任务,通过try-except处理异常确保程序不中断,结合threading实现多线程任务避免阻塞,利用JSON文件保存和加载任务配置实现持久化。 使用Python实现定时任务,主要依赖于schedule模块,它提供了一种简单易懂的方式来安排周期…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信