首页 文章

如何告诉JSON模式验证器从属性值中选择模式?

提问于
浏览
10

例如,文件系统的模式,目录包含文件列表 . 该模式包括文件的规范,接下来是子类型“图像”和另一个“文本” .

底部有主目录模式 . 目录具有属性内容,该属性内容是应该是文件的子类型的项目数组 .

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

Example 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
        }

    ]
}

The "pseudo" Schema 请注意"image"和"text"定义包含在同一模式中,但它们可能在其他地方定义

{
    "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
                ]
            }
        }
    }
}

2 回答

  • 3

    单独的JSON Schema的验证部分不能这样做 - 它代表一个固定的结构 . 您想要的是在验证时解析/引用模式 .

    但是,您可以使用JSON Hyper-Schema和 rel="describedby" 链接表达此信息:

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

    所以在这里,它从 "fileType" 获取值并使用它来计算关系"describedby"的链接 - 这意味着"the schema at this location also describes the current data" .

    问题是大多数验证者都没有注意到任何链接(包括“由”描述的链接) . 你需要找到一个“超验证器” .

    UPDATEtv4库已添加此功能

  • 10

    我认为cloudfeet的答案是一个有效的解决方案 . 您也可以使用相同的方法described here .

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

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

    draft5(正在进行中)已经提出了一个"switch"语句,它将允许以更明确的方式表达替代方案 .

相关问题