如何在JSON Schema Draft-07中实现多条件字段限制?求C++库推荐
问题描述
我正在开发JSON Schema,需求如下:
- 仅允许
type字段及条件允许的字段,存在其他字段则验证失败; - 当
type字段值为Type1时,必须包含字符串字段val1,且仅允许这两个字段; - 支持添加更多类似规则(如
type为Type2时对应val2字段),可设置字段必填/非必填,且Schema不会过于臃肿。
合法示例JSON
{ "type": "Type1", "val1": "1" }
现有实现(Draft-2020-12)
我用unevaluatedProperties实现了需求,但项目里的C++验证器只支持Draft-07,而unevaluatedProperties是Draft-09新增特性。Schema如下:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "type": { "type": "string" } }, "required": ["type"], "unevaluatedProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "Type1" } }, "required": ["type"] }, "then": { "properties": { "val1": { "type": "string" } }, "required": ["val1"] } } ] }
Draft-07单条件实现(存在臃肿问题)
我写了单条件的Draft-07版本,但添加2-3个以上条件时Schema会非常臃肿:
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "type": { "type": "string" }, "val1": { "type": "string" } }, "required": ["type"], "additionalProperties": false, "if": { "properties": { "type": { "const": "Type1" } }, "required": ["type"] }, "then": { "properties": { "type": { "const": "Type1" }, "val1": { "type": "string" } }, "required": ["type", "val1"], "additionalProperties": false }, "else": { "properties": { "type": { "type": "string" } }, "required": ["type"], "additionalProperties": false } }
需要解决:如何在Draft-07下写出不臃肿的多条件Schema,或者推荐支持更高版本的C++ JSON Schema验证库。
解决方案
方案一:优化Draft-07 Schema写法(避免臃肿)
核心思路是用oneOf枚举所有type的分支情况,每个分支明确该类型允许的字段及必填规则,同时通过additionalProperties: false限制额外字段。新增类型时只需添加新的oneOf分支,无需重复基础规则。
示例Schema(包含Type1、Type2两个规则):
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "oneOf": [ { "properties": { "type": { "const": "Type1" }, "val1": { "type": "string" } }, "required": ["type", "val1"], "additionalProperties": false }, { "properties": { "type": { "const": "Type2" }, "val2": { "type": "integer" }, "optVal2": { "type": "string" } // 非必填示例 }, "required": ["type", "val2"], "additionalProperties": false } ] }
优势
- 每个
type分支独立定义,新增规则只需添加新的oneOf项,结构清晰不臃肿; - 天然保证每个类型只能有对应字段,
additionalProperties: false直接限制额外字段; - 可灵活设置每个分支内的必填/非必填字段。
方案二:升级C++验证库(支持更高版本)
如果项目允许升级验证库,推荐以下支持Draft-09+的C++库:
- nlohmann/json-schema-validator:原库的维护分支已支持Draft-2020-12,可直接使用
unevaluatedProperties特性; - rapidjson-schema:基于RapidJSON的验证库,支持Draft-07及更高版本;
- drogonframework/json_schema:Drogon框架附带的验证组件,支持Draft-2020-12,轻量易用。
这些库能直接兼容你原本的Draft-2020-12 Schema,无需修改即可实现需求,避免Draft-07下的写法限制。
内容的提问来源于stack exchange,提问作者Fenix phoenix
相关产品推荐
相关产品推荐

