我正在设计一个带有递归元素的 JSON 模式。该元素不在根,而是在子模式中:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "http://example.org/json-schema/struct.schema.json",
"type": "array",
"items": {
"title": "Structure",
"type": "object",
"properties": {
"id": {
"title": "ID",
"type": "string"
},
"label": {
"title": "Label",
"type": "string"
},
"children": {
"$anchor": "children",
"title": "Children",
"type": "array",
"items": {
"title": "Structure Item",
"type": "object",
"properties": {
"id": {
"title": "ID",
"type": "string"
},
"href": {
"title": "Reference",
"type": "string"
},
"label": {
"title": "Structure Item Label",
"type": "string"
},
"sort_label": {
"title": "Sort Label",
"type": "string"
},
"children": {"$ref": "children"}
}
},
"anyOf": [
{"required": ["id", "href"]},
{"required": ["id", "children"]}
]
}
},
"required": ["id", "label", "children"]
}
}
当我尝试编译模式时,由于
python-fastjsonschema
中的递归,我要么收到错误(使用在线验证器),要么陷入循环(机智items.properties.children
)。
从https://json-schema.org/understanding-json-schema/structuring#recursion中的示例来看,我不清楚什么是允许递归的,什么是不允许的。不允许在
$ref
内递归 $def
,但到根锚点的 $ref
已在有效示例中列出。它们都创建了一个循环(这确实是递归的目的!)。我认为 $ref
对于非根锚点就可以了,但显然不是。
我还尝试使用未命名的锚点,如
"children": {"$ref": "#/items/properties/children"}
中所示,并且架构可以编译,但在验证时抛出错误。
我该如何建模这个模式?
您需要使用
#
符号引用锚点。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "http://example.org/json-schema/struct.schema.json",
"type": "array",
"items": {
"title": "Structure",
"type": "object",
"properties": {
"id": {
"title": "ID",
"type": "string"
},
"label": {
"title": "Label",
"type": "string"
},
"children": {
"$anchor": "children",
"title": "Children",
"type": "array",
"items": {
"title": "Structure Item",
"type": "object",
"properties": {
"id": {
"title": "ID",
"type": "string"
},
"href": {
"title": "Reference",
"type": "string"
},
"label": {
"title": "Structure Item Label",
"type": "string"
},
"sort_label": {
"title": "Sort Label",
"type": "string"
},
"children": {"$ref": "#children"}
}
},
"anyOf": [
{"required": ["id", "href"]},
{"required": ["id", "children"]}
]
}
},
"required": ["id", "label", "children"]
}
}
这是一个路过的实例。
[
{
"id": "",
"label": "",
"children": [
{
"id": "",
"children": []
},
{
"id": "",
"href": ""
}
]
}
]
您可能需要重新考虑您的
anyOf
所需的约束,因为目前对于 anyOf
,它们并不像我认为您希望的那样真正需要。试试oneOf