如何用JSON Schema验证递归树形结构的members字段?
问题
我需要用JSON Schema验证以下树形结构的JSON数据:
{ "type": "node", "members": [ "A", "B" ], "A": { "type": "node", "members": [ "AA", "AB" ], "AA": { "type": "leaf" }, "AB": { "type": "leaf", "1qola": "world" }, "1itn9": 10 }, "B": { "type": "leaf" }, "w81av": 5, "qm8yv": "hello" }
这个结构里的每个节点要么是node要么是leaf,可以带任意数量的子成员和额外属性(比如示例里的w81av、1qola)。
我已经写了一份基础Schema,但不知道怎么验证members字段的有效性——也就是确保members里的每个名称确实对应当前节点的一个属性,同时leaf类型不能有members:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "type": { "type": "string", "enum": ["node", "leaf"] }, "members": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": { "anyOf": [ { "$ref": "#" }, { "type": ["boolean", "number", "string"] } ] }, "required": ["type"] }
解决方案
要搞定members的验证,需要补充三个核心规则,下面是修改后的完整Schema:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "type": { "type": "string", "enum": ["node", "leaf"] }, "members": { "type": "array", "items": { "type": "string" }, "uniqueItems": true // 可选:防止members里出现重复名称 } }, "additionalProperties": { "anyOf": [ { "$ref": "#" }, { "type": ["boolean", "number", "string"] } ] }, "required": ["type"], "allOf": [ // 规则1:leaf类型不能有members字段 { "if": { "properties": { "type": { "const": "leaf" } }, "required": ["type"] }, "then": { "not": { "required": ["members"] } } }, // 规则2:node类型必须有members字段 { "if": { "properties": { "type": { "const": "node" } }, "required": ["type"] }, "then": { "required": ["members"] } }, // 规则3:members里的每个名称必须是当前节点的属性 { "if": { "required": ["members"] }, "then": { "properties": { "members": { "items": { "enum": { "$data": "/keys" } } } } } } ] }
关键细节
- 类型约束:用
if/then分别对leaf和node做规则限制——leaf禁止有members,node必须有members - 成员存在性验证:借助
$data关键字(JSON Schema Draft 2019-09及以上版本支持),动态引用当前对象的所有属性键(/keys),确保members里的每个字符串都是已存在的属性 - 可选去重:
uniqueItems: true可以防止members列表里出现重复的成员名称,根据需求决定是否保留
内容的提问来源于stack exchange,提问作者Mainak Kundu
相关产品推荐
相关产品推荐

