精通 JSON Schema 条件验证:根据枚举值动态设置必填字段

精通 JSON Schema 条件验证:根据枚举值动态设置必填字段

本文深入探讨了如何利用 json schema 的 if/then 结构实现复杂的条件验证,特别是当一个顶级字段的必填性依赖于另一个嵌套字段的特定枚举值时。通过一个实际的订单数据验证案例,文章详细讲解了如何构建精准的条件逻辑,确保数据模型在不同业务场景下的灵活性和准确性,避免常见的验证错误。

在数据交换和存储中,JSON Schema 是定义和验证数据结构的标准工具。然而,业务逻辑往往并非一成不变,某些字段的必填性可能需要根据其他字段的值动态调整。这种“条件必填”的需求,正是 JSON Schema 中 if/then/else 关键字所擅长解决的问题。

核心挑战:根据嵌套字段值动态要求字段

设想一个订单管理系统,其中包含不同类型的操作(例如“ORDER”、“TRANSFER”、“WITHDRAWAL”等)。对于类型为“ORDER”的订单,我们要求必须提供商品列表(items 字段);而对于其他类型的订单,items 字段则不是必需的。

最初的尝试可能是在 attributes 内部的 allOf 块中,针对 order_type 为 “ORDER” 的情况,尝试添加 required: [“items”]。然而,这种做法通常会导致验证失败,因为 items 是顶层属性,而不是 attributes 内部的属性。if/then 关键字的应用范围是其所在模式的实例,因此在 attributes 内部声明 required: [“items”] 意味着要求 attributes 对象本身包含 items 属性,这显然与我们的设计不符。

JSON Schema 条件验证机制 (if/then)

JSON Schema Draft 07 引入的 if、then 和 else 关键字提供了强大的条件逻辑能力:

if: 定义一个子模式作为条件。如果数据实例符合 if 中定义的模式,则应用 then 中定义的模式。then: 当 if 条件满足时应用的子模式。else: 当 if 条件不满足时应用的子模式(可选)。

理解 if 关键字的关键在于,它所描述的条件是针对当前正在被验证的整个数据实例而言的。这意味着,即使条件是基于嵌套属性的值,if 块本身也需要描述如何定位到这个嵌套属性。

正确实现方案

为了解决上述问题,我们需要将条件验证逻辑放在顶层,并精确地描述 attributes.order_type 的路径和值。以下是经过优化的 JSON Schema 示例:

{  "$schema": "http://json-schema.org/draft-07/schema#",  "title": "Validaciones sobre el esquema Order",  "type": "object",  "properties": {    "warehouse_id": {      "type": "string"    },    "operation_type": {      "type": "string"    },    "order_id": {      "type": "number"    },    "items": {      "type": "array",      "minItems": 1,      "items": {        "type": "object",        "properties": {          "sku": {            "type": "string",            "minLength": 1,            "maxLength": 50          },          "quantity": {            "type": "integer",            "minimum": 1          }        },        "required": [          "sku",          "quantity"        ],        "additionalProperties": false      }    },    "attributes": {      "type": "object",      "properties": {        "order_type": {          "type": "string",          "enum": [            "ORDER",            "TRANSFER",            "WITHDRAWAL",            "DISPOSAL",            "FRESH"          ]        },        "etd": {          "type": "string",          "pattern": "^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])(?:T)(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]):(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])(?:Z)$"        },        "volume": {          "type": [            "integer",            "null"          ],          "minimum": 0        },        "typology": {          "type": [            "string",            "null"          ],          "enum": [            "CONVEYABLE",            "NON_CONVEYABLE"          ]        }      },      "required": [        "order_type"      ],      "additionalProperties": false    }  },  "required": [    "warehouse_id",    "operation_type",    "attributes"  ],  "additionalProperties": false,  "allOf": [    {      "if": {        "properties": {          "attributes": {            "properties": {              "order_type": {                "const": "ORDER"              }            },            "required": [              "order_type"            ]          }        },        "required": [          "attributes"        ]      },      "then": {        "required": [          "items"        ]      }    }  ]}

关键解析

allOf 的位置: 条件逻辑被放置在最顶层的 allOf 数组中。allOf 确保所有子模式都必须通过验证。if 子句:if 内部的结构描述了如何定位到 order_type 属性。它不是简单地写 order_type,而是从根层级开始,通过 properties 逐步深入到 attributes 对象,再到 order_type 属性。”properties”: { “attributes”: { … } }:这表示我们关注的是顶层 properties 中的 attributes 属性。”attributes”: { “properties”: { “order_type”: { “const”: “ORDER” } }, “required”: [“order_type”] }:这进一步描述了 attributes 属性本身是一个对象,它包含一个 order_type 属性,且该属性的值必须是 “ORDER”。同时,为了确保 order_type 确实存在,我们也在 attributes 内部声明 required: [“order_type”]。”required”: [“attributes”]:确保顶层数据中必须包含 attributes 属性,这是访问 order_type 的前提。then 子句:”then”: { “required”: [“items”] }:当 if 条件(即 attributes.order_type 为 “ORDER”)满足时,items 属性在顶层被声明为必填。

通过这种方式,我们精确地表达了“如果数据实例中存在 attributes 且 attributes.order_type 的值为 “ORDER”,那么 items 属性必须存在”的逻辑。

验证实例

让我们通过几个示例来验证这个 Schema 的行为:

Qoder Qoder

阿里巴巴推出的AI编程工具

Qoder 270 查看详情 Qoder

1. 无效数据示例:order_type 为 “ORDER” 但缺少 items

{    "warehouse_id": "ARTW01",    "operation_type": "outbound",    "order_id": 41789301078,    "attributes": {        "volume": 1350,        "etd": "2022-11-11T18:25:00Z",        "order_type": "ORDER"    }}

验证结果: 失败。因为 order_type 是 “ORDER”,根据 then 规则,items 字段是必需的,但此数据中缺少。

2. 有效数据示例:order_type 为 “ORDER” 且包含 items

{    "warehouse_id": "ARTW01",    "operation_type": "outbound",    "order_id": 41789301078,    "items": [        {            "sku": "SKU001",            "quantity": 5        }    ],    "attributes": {        "volume": 1350,        "etd": "2022-11-11T18:25:00Z",        "order_type": "ORDER"    }}

验证结果: 成功。条件满足,且 items 字段存在并符合其自身的模式定义。

3. 有效数据示例:order_type 不为 “ORDER” 且缺少 items

{    "warehouse_id": "ARTW01",    "operation_type": "inbound",    "order_id": 41789301079,    "attributes": {        "volume": 200,        "etd": "2022-11-12T10:00:00Z",        "order_type": "TRANSFER"    }}

验证结果: 成功。if 条件不满足,因此 then 规则不被应用,items 字段不是必需的。

注意事项与最佳实践

理解 if 的作用域: if 关键字的条件是针对其所在的 JSON Schema 节点所验证的整个数据实例。因此,当条件涉及嵌套属性时,需要在 if 内部完整地描述该属性的路径。required 关键字的放置: required 关键字声明的是当前模式级别下的必填属性。在上述示例中,items 是顶层属性,所以其必填性声明在顶层 then 块中。allOf 的灵活性: allOf 可以用于组合多个条件逻辑或多个子模式,使其共同作用于数据实例。保持模式简洁: 在开发和调试时,可以像答案中那样,暂时移除不相关的 Schema 部分,只关注条件验证的核心逻辑,以提高可读性和定位问题。充分测试: 对于复杂的条件验证,务必准备多组测试数据,覆盖所有条件分支(条件满足、条件不满足、边界情况),确保 Schema 行为符合预期。

总结

JSON Schema 的 if/then 关键字为处理复杂的、基于数据内容的条件验证提供了强大而灵活的机制。通过精确地定义条件 (if) 和对应的验证规则 (then),我们可以构建出能够适应多变业务需求的健壮数据模型。掌握这种高级用法,将极大地提升数据验证的准确性和系统的可靠性。

以上就是精通 JSON Schema 条件验证:根据枚举值动态设置必填字段的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/959144.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何使用CSS Grid实现首页模块化布局_网格布局设计实践
上一篇 2025年12月1日 18:32:58
国产手机面板雄起!明年全球占比有望超70%
下一篇 2025年12月1日 18:33:04

相关推荐

  • 放大招!文心一言「全面免费」,同时开启「深度搜索」,抢鲜实测!

    放大招!文心一言「全面免费」,同时开启「深度搜索」,抢鲜实测!放大招!文心一言「全面免费」,同时开启「深度搜索」,抢鲜实测!放大招!文心一言「全面免费」,同时开启「深度搜索」,抢鲜实测!放大招!文心一言「全面免费」,同时开启「深度搜索」,抢鲜实测!

    2025年伊始,大模型技术再创新高!百度文心一言宣布,自4月1日零时起,pc端和app端全面免费开放,用户可体验文心系列最新模型,以及超长文档处理、专业检索增强、高级ai绘画、多语种对话等功能。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜…

    2026年9月2日 用户投稿
    200
  • b站24小时直播入口快速通道-b站24小时直播入口实时弹幕互动

    b站没有专门的24小时直播入口,但可通过首页推荐、分区浏览、搜索关键词、关注主播或使用第三方聚合平台快速找到正在直播的内容,进入直播间并登录账号后即可在输入框发送弹幕参与实时互动,还可使用彩色或高级弹幕增强趣味性,需注意文明发言,b站直播涵盖游戏、娱乐、知识、生活及虚拟主播等多种类型,若找不到想看的…

    2026年9月2日
    000
  • App视频播放如何添加全屏不遮挡文字水印?

    App视频播放全屏水印的挑战与解决方案 为App视频播放添加全屏显示且不遮挡视频内容的文字水印,是许多开发者面临的难题,尤其是在保证iOS和Android系统兼容性的前提下。本文将探讨如何解决“如何在App前端为video视频播放添加全屏不遮挡文字水印,并兼容iOS和Android”这一问题。 直接…

    2026年9月2日
    000
  • 从复杂到简洁:如何用 Composer 轻松安装 Ibexa Commerce

    可以通过以下地址学习 composer:学习地址 在开发一个电商平台时,选择一个合适的框架和工具集是至关重要的。我最初尝试了多种开源和商业解决方案,但它们要么功能不全,要么安装过程过于复杂。直到我找到了 Ibexa Commerce,这是一个基于 Symfony 的全栈解决方案,提供了丰富的功能和灵…

    用户投稿 2026年9月2日
    000
  • 学而思发布全新“随时问”APP,DeepSeek随便用

    全教育行业拥抱deepseek的浪潮还在继续,在产品层面的落地和结合也开始带来惊喜。 学而思今天正式发布接入DeepSeek的全新“随时问”APP。该产品深度融合DeepSeek R1智能推理,依托学而思22年教研沉淀,现面向全国中小学生免费开放,提供苏格拉底式启发学习模式,支持题目分步解析、无限追…

    2026年9月2日
    000
  • 封神:开天曹宝全解析:法力永动机与阵容搭配终极指南

    封神:开天曹宝全解析:法力永动机与阵容搭配终极指南封神:开天曹宝全解析:法力永动机与阵容搭配终极指南封神:开天曹宝全解析:法力永动机与阵容搭配终极指南封神:开天曹宝全解析:法力永动机与阵容搭配终极指南

    还在为队伍法力耗尽而苦恼?《封神:开天》xp1赛季的强力辅助曹宝,正是你扭转战局的关键人物!这位表面低调的仙家角色,凭借其颠覆战场的回蓝技能与战略级灵宝,成功登顶当前版本最强辅助! 法力源泉:曹宝核心机制深度剖析【借灵献宝】——群体回蓝利器! 只需消耗5点法力值,曹宝便能发动这一逆天技能。技能满级时…

    2026年9月2日 用户投稿
    000
  • win8剪贴板在哪里查看 win8系统剪贴板历史记录查看方法

    Windows 8不支持剪贴板历史记录,只能通过Ctrl+V粘贴最近一次内容;可升级至Windows 10使用Win+V查看历史,或安装Ditto等第三方工具实现多条目管理。 如果您在使用Windows 8系统时需要查找之前复制的内容,但发现系统并未提供直接的剪贴板历史记录查看功能,则可以通过以下方…

    2026年9月2日
    000
  • 悟空浏览器看动漫好卡怎么办 解决动漫播放卡顿的3个有效技巧

    悟空浏览器看动漫卡顿,通常由网络连接不稳定、浏览器设置不当或设备性能不足导致。首先应优化网络环境,确保wi-fi信号强,避免多设备争抢带宽,必要时改用有线连接,并重启路由器以清除缓存;同时降低视频清晰度以减轻网络负担。其次调整浏览器设置,定期清理缓存和cookie,尝试开启或关闭硬件加速以适配设备性…

    2026年9月2日
    000
  • 使用 Composer 简化 Laravel 和 Vue 的集成:ycgambo/laravel-vue-templates 库的实践

    可以通过以下地址学习 composer:学习地址 在开发过程中,我发现 Laravel 和 Vue 的集成是一个常见但复杂的挑战。传统上,我们有两种选择:一是将 Laravel 作为 API 服务器并独立部署一个 Vue 应用,二是完全放弃 Vue,转而使用 Laravel 的 Blade 模板引擎…

    用户投稿 2026年9月2日
    100
  • 使用 Composer 简化 S3 存储数据传输:wbtdc/s3copy 库的实际应用

    可以通过一下地址学习composer:学习地址 在项目开发中,数据传输是一个常见的需求,特别是当我们需要将数据存储到云端时。S3 兼容的存储服务如 Wasabi 和 Amazon S3 因其高效和可靠性而广受欢迎。然而,如何高效地将数据传输到这些服务上却是一个挑战。经过一番尝试,我发现了 wbtdc…

    用户投稿 2026年9月2日
    000
  • 半年估值翻 3 倍,Cursor 冲刺 270 亿美元

    据 the information 消息,coatue 与 accel 正在与知名 ai 编程工具 cursor 的母公司 anysphere 就一笔不低于10亿美元的融资进行深入谈判,此轮融资前估值或达到惊人的270亿美元。 早在今年6月,Accel 曾以99亿美元的估值参与其上一轮投资,短短数月…

    2026年9月2日
    000
  • 电脑剪切板在哪 简单几招快速找到

    电脑剪切板在哪 简单几招快速找到电脑剪切板在哪 简单几招快速找到电脑剪切板在哪 简单几招快速找到电脑剪切板在哪 简单几招快速找到

    当你在电脑上复制一段文字或剪切一张图片时,这些内容并不会立即消失,而是被临时存放在一个名为“剪切板”的系统区域中。但很多用户都会好奇:这个剪切板究竟在哪里?又该如何查看里面的内容?本文将为你全面解析剪切板的位置与使用方法,助你轻松掌握技巧,提升操作效率。 一、Windows 剪切板功能详解 剪切板是…

    2026年9月2日 用户投稿
    100
  • 标题: 如何使用 Composer 简化比利时结构化通信的生成与验证

    可以通过以下地址学习composer:学习地址 文章内容: 最近在开发一个面向比利时的财务管理系统时,我遇到了一个令人头疼的问题:如何高效地生成和验证比利时的结构化通信(Structured Communication)。这种通信格式在比利时的金融交易中广泛使用,但其生成和验证的规则较为复杂,容易出…

    用户投稿 2026年9月2日
    000
  • 电脑屏幕旋转了90度怎么调回来 一键恢复

    电脑屏幕旋转了90度怎么调回来 一键恢复电脑屏幕旋转了90度怎么调回来 一键恢复电脑屏幕旋转了90度怎么调回来 一键恢复电脑屏幕旋转了90度怎么调回来 一键恢复

    在使用电脑的过程中,可能会因误触某些快捷键,导致屏幕意外旋转90度或180度,造成画面颠倒、操作困难。这种问题通常由快捷键误操作、显示设置变动或显卡驱动异常引起。下面介绍几种有效的解决办法。 方法一:使用快捷键快速恢复 若屏幕旋转是由于误触快捷键所致,可通过以下组合键迅速调整: Ctrl + Alt…

    2026年9月2日 用户投稿
    100
  • 网易有道开源“子曰3”数学模型:低成本AI加速教育渗透

    6月23日,网易有道宣布正式开源“子曰3”系列大模型中的数学模型(英文名:confucius3-math)。这是国内首个专注于数学教育、可在单块消费级gpu上高效运行的开源推理模型。该模型在多项数学推理任务中表现卓越,取得当前最优成绩,甚至超越了许多规模更大的通用大模型。此次开源为教育行业提供了低成…

    2026年9月2日
    000
  • 如何训练最强代码大模型?北大aiXcoder-7B贡献前沿实践

    如何训练最强代码大模型?北大aiXcoder-7B贡献前沿实践如何训练最强代码大模型?北大aiXcoder-7B贡献前沿实践如何训练最强代码大模型?北大aiXcoder-7B贡献前沿实践如何训练最强代码大模型?北大aiXcoder-7B贡献前沿实践

    北京大学aixcoder团队的代码大模型aixcoder-7b,在软件工程领域顶级会议icse 2025上发表论文,并将于4月27日至5月3日在加拿大渥太华分享研究成果。该模型将抽象语法树(ast)结构与大规模预训练相结合,提升了对代码结构和上下文的理解能力,并在企业应用中获得广泛认可。 ☞☞☞AI…

    2026年9月2日 用户投稿
    100
  • 如何可靠地将复杂的LaTeX公式转换为可执行代码?

    LaTeX公式到可执行代码的可靠转换:挑战与策略 许多科研人员和工程师面临将LaTeX公式转换为可用于编程语言(如Python或JavaScript)进行计算的代码的难题。LaTeX侧重排版而非计算逻辑,直接转换并非易事。本文探讨如何将LaTeX公式字符串转换为可执行代码。 一个实际案例: {P}_…

    2026年9月2日
    000
  • win11声音太小怎么办_解决Win11音量过低和声音增强设置

    首先检查任务栏音量是否调至最大,再通过设置调整应用音量、启用增强音频功能,更新音频驱动,并可借助第三方软件进一步提升音量。 如果您在使用Windows 11时发现系统或应用程序的音量过低,影响了正常的音频体验,则可能是由于系统设置、设备配置或驱动问题导致。以下是解决此问题的具体操作步骤: 本文运行环…

    2026年9月2日
    100
  • 使用 Composer 管理 PHP 配置:phpf/config 库的应用

    可以通过以下地址学习 composer:学习地址 在开发大型 PHP 项目时,配置管理是一个不可避免的挑战。我曾经尝试使用简单的 PHP 数组来管理配置,但随着项目的扩展,这种方法变得难以维护和扩展。后来,我发现了 phpf/config 库,它通过 Composer 轻松集成,为我的项目带来了显著…

    用户投稿 2026年9月2日
    000
  • 跑腿代办神器!即时同城服务App开发

    你是否也曾被这些琐碎事务困扰? 急需跨城送达的文件,快递来不及?热门餐厅美食诱人却排起长队? 加班无暇照顾家中宠物,它正等着喂食? 人在外地出差,家里的水电煤费用即将逾期? 这些正是即时同城服务平台应运而生的原因!通过移动互联网与LBS定位技术,平台将本地用户和服务者高效连接,轻松实现“代买、代送、…

    2026年9月2日
    000

发表回复

登录后才能评论
关注微信