关于 $ref 使用的 JSON 模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17595377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:56:33  来源:igfitidea点击:

JSON Schema regarding use of $ref

jsonjsonschema

提问by hunterc

I understand that $ref takes a URI to a json schema to use but where does $ref : "#" point to? Does it just mean use the current schema for this block level? Or does it mean to use the root level schema defined in the root level id? Thanks

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

EDIT: So if I have:

编辑:所以如果我有:

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

Because it lacks an id field it will attempt to validate the instance items with the root schema first and then if that fails try to validate it with the schemaArray schema defined in the definitions schema, right?

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

So if I change it to:

所以如果我把它改成:

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

Then the first subschema in anyOf array will point to the items schema itself?

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

EDIT #2: Okay so if I had:

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

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

and

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

"stringArray"'s "items" field would be validated against the above "itemsSchema"?

“stringArray”的“items”字段将根据上述“itemsSchema”进行验证?

Also does the second $ref in 'anyOf' work by going to the root and then traversing down the path till it hits that schema? Thanks!

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

回答by cloudfeet

OK: each $refis resolved into a full URI. Once that is done, all your questions are answered by asking the question: What schema would I end up with, if I simply fetched that URI?Where the $refis, how it was loaded, all of that is irrelevant - it's entirelydependent on the resolved URI.

OK:每​​个都$ref被解析为一个完整的 URI。完成后,您的所有问题都会通过提出以下问题来回答:如果我只是获取该 URI,我最终会得到什么模式?它在哪里$ref,它是如何加载的,所有这些都无关紧要 - 它完全取决于解析的 URI。

The library mighttake some shortcuts (like caching documents so they are only fetched once, or trusting one schema to "speak for" another), but those are all implementation details.

可能会采取一些捷径(例如缓存文档以便它们只被提取一次,或者信任一个模式来“代表”另一个模式),但这些都是实现细节。

Response to original question:

对原始问题的回答:

#is not special: all values of $refare resolved as URIs relative to the current document (or the closest value of "id", if there is one).

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

Therefore, if you haven't used "id", then #will point to the root of the schema document. If you fetched your schema from http://example.com/schema, then a {"$ref": "#"}anywhereinside that will resolve to http://example.com/schema#, which is the document itself.

因此,如果您还没有使用"id"#则将指向架构文档的根。如果您从 获取架构http://example.com/schema,则内部的{"$ref": "#"}任何地方都将解析为http://example.com/schema#,即文档本身。

It is different when you use "id", because it changes the "base" schema against which the $refis resolved:

当你使用时它是不同的"id",因为它改变了$ref解析的“基本”模式:

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

In that example, the $refresolves to http://example.com/item-schema#. Now, if your JSON Schema setup truststhe schema it already has, then it can re-use the value from "items".

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

However, the point is there is nothing special about #- it just resolves to a URI like any other.

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

Response to EDIT 1:

对编辑 1 的回应:

Your first example is correct.

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

However, your second is unfortunately not. This is because of the way that fragments resolution works for URIs: one fragment completely replacesanother. When you resolve the #against the "id"value of #/items, you don't end up with #/itemsagain - you end up with #. So in your second example, the first entry in "anyOf"will still resolve to the root of the document, just as in the first example.

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

Response to EDIT 2:

对编辑 2 的回应:

Assuming the document is loaded from http://example.com/my-schema, the full URIs of your two $refs are:

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

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

For the first one, the library mayuse the schema it already has, but it might not - after all, looking at the URIs, http://example.com/my-schemamight not be trusted to accurately represent http://example.com/itemSchema.

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

For the second one - that's not going to work, because the "itemSchema" doesn't have a "definitions"section, so that $refwon't resolve properly at all.

对于第二个 - 这是行不通的,因为“itemSchema”没有"definitions"节,因此$ref根本无法正确解析。