关于使用$ ref的JSON Schema

hun*_*erc 30 json jsonschema

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

编辑:所以,如果我有:

"items": {
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }
Run Code Online (Sandbox Code Playgroud)

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

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

 "items": {
            "id" : "#/items",
            "anyOf": [
                { "$ref": "#" },
                { "$ref": "#/definitions/schemaArray" }
            ],
            "default": {}
        }
Run Code Online (Sandbox Code Playgroud)

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

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

 "items": {
        "id" : "itemSchema",
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }
Run Code Online (Sandbox Code Playgroud)

"stringArray": {
        "type": "array",
        "items": { "$ref" : "itemSchema" },
        "minItems": 1,
        "uniqueItems": true
    }
Run Code Online (Sandbox Code Playgroud)

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

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

clo*_*eet 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": "#"}
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

对编辑1的回应:

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

但是,不幸的是,你的第二个不是.这是因为片段解析对URI起作用的方式:一个片段完全取代另一个片段.当您解决#反对"id"的价值#/items,你不就结了#/items一次-你结束了#.因此,在第二个示例中,第一个条目"anyOf"仍将解析为文档的根,就像在第一个示例中一样.

对编辑2的回应:

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

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

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

对于第二个 - 这不会起作用,因为"itemSchema"没有一个"definitions"部分,因此$ref根本无法正确解析.