34

$ref が使用する json スキーマへの URI を取ることは理解していますが、 $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」の 2 番目の $ref は、ルートに移動してから、そのスキーマに到達するまでパスをたどることで機能しますか? ありがとう!

4

1 に答える 1

37

OK: それぞれ$refが完全な URI に解決されます。それが完了すると、次の質問をすることで、すべての質問に答えます。単純にその URI を取得した場合、最終的にどのようなスキーマになるでしょうか? がどこに$refあるのか、どのようにロードされたのか、そのすべては無関係です。解決された URI に完全に依存しています。

ライブラリいくつかの近道をとることもありますが (ドキュメントをキャッシュして 1 回だけフェッチされるようにしたり、1 つのスキーマを信頼して別のスキーマを "代弁する" など)、それらはすべて実装の詳細です。

元の質問への回答:

#は特別なものではありません: のすべての値は$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 への応答:

最初の例は正しいです。

ただし、残念ながら2番目はそうではありません。これは、フラグメント解決が URI に対して機能する方法によるものです。1 つのフラグメントが別のフラグメントを完全に置き換えます。の値#に対してを解決すると、再びではなく、 になります。したがって、2 番目の例では、最初の例と同様に、最初のエントリがドキュメントのルートに解決されます。"id"#/items#/items#"anyOf"

編集 2 への応答:

ドキュメントが からロードされると仮定すると、http://example.com/my-schema2 つの の完全な URI は次のようになります$ref

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

最初のものについては、ライブラリはすでに持っているスキーマを使用するかもしれませんが、そうではないかもしれません - 結局、URI を見るとhttp://example.com/my-schemahttp://example.com/itemSchema.

2 つ目については、「itemSchema」に"definitions"セクション$refがないため、正しく解決されないため、うまくいきません。

于 2013-07-18T12:14:07.930 に答える