JSON 模式中的递归项

问题描述 投票:0回答:1

我正在设计一个带有递归元素的 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"}
中所示,并且架构可以编译,但在验证时抛出错误。

我该如何建模这个模式?

recursion jsonschema json-schema-validator
1个回答
0
投票

您需要使用

#
符号引用锚点。

{
    "$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

© www.soinside.com 2019 - 2024. All rights reserved.