34

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

编辑:所以如果我有:

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

因为它缺少一个 id 字段,它会首先尝试使用根模式验证实例项,然后如果失败,则尝试使用定义模式中定义的 schemaArray 模式验证它,对吧?

因此,如果我将其更改为:

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

那么 anyOf 数组中的第一个子模式将指向项目模式本身吗?

编辑#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 是否通过转到根目录然后遍历路径直到它到达该模式来工作?谢谢!

4

1 回答 1

37

OK:每​​个都$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 Schema 设置信任它已有的模式,那么它可以重新使用“items”中的值。

然而,关键是没有什么特别之处#——它只是像其他任何东西一样解析为一个 URI。

对编辑 1 的回应:

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

但是,不幸的是,您的第二个不是。这是因为片段解析适用于 URI 的方式:一个片段完全替换另一个片段。当您解决#反对 的"id"价值时#/items,您不会#/items再次以 . 结束 - 您以 . 结束#。因此,在您的第二个示例中,第一个条目"anyOf"仍将解析为文档的根目录,就像在第一个示例中一样。

对编辑 2 的回应:

假设文档是从 加载的,那么您的两个shttp://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根本无法正确解决。

于 2013-07-18T12:14:07.930 回答