首页 文章

关于使用$ ref的JSON Schema

提问于
浏览
28

我知道$ ref需要一个URI来使用json架构,但$ ref:“#”指向哪里?它只是意味着使用此块级别的当前架构吗?或者是否意味着使用根级别ID中定义的根级别架构?谢谢

编辑:所以,如果我有:

"items": {
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }

因为它缺少id字段,所以它将首先尝试使用根模式验证实例项,然后如果失败则尝试使用定义模式中定义的schemaArray模式对其进行验证,对吗?

所以,如果我将其更改为:

"items": {
            "id" : "#/items",
            "anyOf": [
                { "$ref": "#" },
                { "$ref": "#/definitions/schemaArray" }
            ],
            "default": {}
        }

然后anyOf数组中的第一个子模式将指向items模式本身?

编辑#2:好的,如果我有:

"items": {
        "id" : "itemSchema",
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }

"stringArray": {
        "type": "array",
        "items": { "$ref" : "itemSchema" },
        "minItems": 1,
        "uniqueItems": true
    }

“stringArray”的“items”字段是否会针对上述“itemsSchema”进行验证?

'anyOf'中的第二个$ ref也通过转到root然后遍历路径直到它到达该模式来工作吗?谢谢!

1 回答

  • 35

    OK:每个 $ref 都被解析为完整的URI . 完成后,通过提出问题来回答所有问题: What schema would I end up with, if I simply fetched that URI? $ref 的位置,加载方式,所有这些都无关紧要 - 它完全取决于已解析的URI .

    库可能需要一些快捷方式(比如缓存文档,因此它们只被提取一次,或者信任一个模式到另一个模式),但这些都是实现细节 .

    对原始问题的回复:

    # 并不特殊: $ref 的所有值都被解析为相对于当前文档的URI(或者最接近的值 "id" ,如果有的话) .

    因此,如果您尚未使用 "id" ,则 # 将指向架构文档的根目录 . 如果您从 http://example.com/schema 获取了架构,那么内部的任何地方都将解析为 http://example.com/schema# ,这是文档本身 .

    使用 "id" 时会有所不同,因为它会更改"base"解析 $ref 的架构:

    {
        "type": "array",
        "items": {
            "id": "http://example.com/item-schema",
            "type": "object",
            "additionalProperties": {"$ref": "#"}
        }
    }
    

    在该示例中, $ref 解析为 http://example.com/item-schema# . 现在,如果您的JSON Schema设置信任它已有的模式,那么它可以重用"items"中的值 .

    然而,关键是 # 并没有什么特别之处 - 它只是解析为一个像任何其他URI一样的URI .

    对编辑1的回应:

    你的第一个例子是正确的 .

    但是,不幸的是,你的第二个不是 . 这是因为片段解析对URI起作用的方式:一个片段完全取代另一个片段 . 当您针对 #/items"id" 值解析 # 时,您不会再次使用 #/items - 最终会得到 # . 因此,在第二个示例中, "anyOf" 中的第一个条目仍将解析为文档的根,就像在第一个示例中一样 .

    对编辑2的回应:

    假设文档是从 http://example.com/my-schema 加载的,那么两个 $ref 的完整URI是:

    • http://example.com/itemSchema#

    • http://example.com/itemSchema#/definitions/schemaArray

    对于第一个,库 may 使用它已有的模式,但它可能不会 - 毕竟,查看URI, http://example.com/my-schema 可能不被信任准确表示 http://example.com/itemSchema .

    对于第二个 - 's not going to work, because the 1487381 doesn' t有一个 "definitions" 部分,因此 $ref 根本无法正确解析 .

相关问题