如何通过JSON Schema动态引用数组实现成员名单合法性校验?
问题分析
你尝试用enum结合$data通配符引用学生名单的方法行不通,原因是JSON Schema的$data关键字不支持通配符*,它只能引用明确的JSON路径,无法自动提取数组中所有元素的某个字段组成枚举列表,所以校验时会把"$data/students/details/*/name"当成一个普通字符串值,导致校验逻辑错误。
正确解决方案
要实现“图书馆会员必须是在校学生”的校验,需要利用JSON Schema draft-2020-12版本的特性,通过contains关键字结合$data动态引用,检查每个会员的姓名是否存在于学生名单中。
完整校验Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "students": { "type": "object", "required": ["details"], "properties": { "schoolName": {"type": "string"}, "isEnrolled": {"type": "boolean"}, "details": { "type": "array", "items": { "type": "object", "required": ["name"], "properties": { "name": {"type": "string"} } } } } }, "libMembership": { "type": "array", "items": { "type": "object", "required": ["members"], "properties": { "membershipType": {"type": "string"}, "members": { "type": "array", "items": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "allOf": [ { "$data": "/students/details", "contains": { "properties": { "name": {"const": {"$data": "0"}} }, "required": ["name"] } } ] } } } } } } } }, "required": ["students", "libMembership"] }
核心逻辑说明
- 指定使用draft-2020-12版本的Schema,确保
$data和contains的组合能正常工作 - 针对
libMembership.members中的每个姓名:- 通过
"$data": "0"引用当前待校验的会员姓名 - 检查
/students/details数组中是否存在一个元素,其name字段等于当前会员姓名(通过contains+const实现)
- 通过
- 当会员姓名(比如
emmanuel)不在学生名单中时,contains校验失败,会触发对应的ValidationError
校验结果
用你提供的测试数据运行校验,会正确抛出错误,提示该会员姓名不在学生名单中(具体错误信息根据校验库略有差异)
内容的提问来源于stack exchange,提问作者Sam Affan
相关产品推荐
相关产品推荐

