关于使用$ ref的JSON Schema

时间:2013-07-11 13:57:24

标签: json jsonschema

我知道$ 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 个答案:

答案 0 :(得分:35)

好的:每个$ref都会被解析为完整的URI。完成后,通过提出问题来回答您的所有问题:如果我只是提取了该URI,我会得到什么模式? $ref的位置,加载方式,所有这些都是无关紧要的 - 它完全依赖于已解析的URI。

可能采取一些快捷方式(比如缓存文档,因此它们只被提取一次,或者信任一个模式“为另一个”说话),但这些都是实现细节。

对原始问题的回复:

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

因此,如果您尚未使用"id",则#将指向架构文档的根目录。如果您从http://example.com/schema获取了架构,那么内部的{"$ref": "#"} 将解析为http://example.com/schema#,即文档本身。

使用"id"时会有所不同,因为它会更改解决$ref的“基础”架构:

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

在该示例中,$ref解析为http://example.com/item-schema#。现在,如果您的JSON架构设置信任它已有的架构,那么它可以重新使用“items”中的值。

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

对编辑1的回应:

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

然而,遗憾的是,你的第二个不是。这是因为片段解析对URI起作用的方式:一个片段完全替换另一个片段。当您针对# "id"#/items解析#/items时,您最终不会再次使用# - 最终会得到"anyOf"。因此,在第二个示例中,http://example.com/my-schema中的第一个条目仍将解析为文档的根,就像在第一个示例中一样。

对编辑2的回应:

假设文档是从$ref加载的,则两个http://example.com/itemSchema#的完整URI是:

  • http://example.com/itemSchema#/definitions/schemaArray
  • http://example.com/my-schema

对于第一个,库可能使用它已有的架构,但它可能不会 - 毕竟,查看URI,http://example.com/itemSchema可能不被信任以准确表示"definitions"

对于第二个 - 这不起作用,因为“itemSchema”没有$ref部分,因此{{1}}根本无法正确解析。