13

例如文件系统的模式,目录包含文件列表。模式由文件规范、下一个子类型“图像”和另一个“文本”组成。

底部是主目录架构。目录有一个属性内容,它是一个项目数组,应该是文件的子类型。

基本上,我正在寻找一种方法来告诉验证器从正在验证的 json 对象中的属性中查找“$ref”的值。

示例 json:

{
    "name":"A directory",
    "content":[
        {
            "fileType":"http://x.y.z/fs-schema.json#definitions/image",
            "name":"an-image.png",
            "width":1024,
            "height":800
        }
        {
            "fileType":"http://x.y.z/fs-schema.json#definitions/text",
            "name":"readme.txt",
            "lineCount":101
        }
        {
            "fileType":"http://x.y.z/extended-fs-schema-video.json",
            "name":"demo.mp4",
            "hd":true
        }

    ]
}

“伪”模式注意到“图像”和“文本”定义包含在同一个模式中,但它们可能在其他地方定义

{
    "id": "http://x.y.z/fs-schema.json",
    "definitions": {
        "file": {
            "type": "object",
            "properties": {
                "name": { "type": "string" },
                "fileType": {
                    "type": "string",
                    "format": "uri"
                }
            }
        },
        "image": {
            "allOf": [
            { "$ref": "#definitions/file" },
            {
                "properties": {
                    "width": { "type": "integer" },
                    "height": { "type": "integer"}
                }
            }
            ]
        },
        "text": {
            "allOf": [
            { "$ref": "#definitions/file" },
            { "properties": { "lineCount": { "type": "integer"}}}
            ]
        }
    },
    "type": "object",
    "properties": {
        "name": { "type": "string"},
        "content": {
            "type": "array",
            "items": {
                "allOf": [
                { "$ref": "#definitions/file" },
                { *"$refFromProperty"*: "fileType" } // the magic thing
                ]
            }
        }
    }
}
4

2 回答 2

10

仅 JSON Schema 的验证部分无法做到这一点——它代表了一个固定的结构。您想要的需要在验证时解析/引用模式。

但是,您可以使用 JSON Hyper-Schema 和rel="describedby"链接来表达这一点:

{
    "title": "Directory entry",
    "type": "object",
    "properties": {
        "fileType": {"type": "string", "format": "uri"}
    },
    "links": [{
        "rel": "describedby",
        "href": "{+fileType}"
    }]
}

所以在这里,它取值"fileType"并使用它来计算与关系“描述者”的链接——这意味着“这个位置的模式也描述了当前数据”。

问题是大多数验证器不会注意到任何链接(包括“描述的”链接)。您需要找到一个“超级验证器”。

更新tv4库已将此作为功能添加

于 2013-10-17T11:35:48.423 回答
3

我认为 cloudfeet 的答案是一个有效的解决方案。您也可以使用此处描述的相同方法。

您将拥有一个文件对象类型,它可以是您要定义的所有子类型的“anyOf”。您将使用枚举以便能够引用和验证每个子类型。

如果子类型架构在同一个 Json-Schema 文件中,则不需要使用“$ref”显式引用 uri。正确的 draft4 验证器将找到枚举值,并将尝试针对 Json-Schema 树中的“子模式”进行验证。

草案 5(正在进行中)中,已经提出了一个“转换”声明,这将允许以更明确的方式表达替代方案。

于 2013-10-17T18:38:35.753 回答