4

JSON スキーマを参照して再利用するために、 JSON ポインターを試してきました。

例に従って、別の JSON スキーマで宣言された特定のプロパティを参照でき、すべてが期待どおりに進みますが、明示的に参照することなく、別の基本スキーマの定義で基本 JSON スキーマを拡張する方法が見つかりませんでしたすべてのプロパティ。

これは便利なようですが、可能かどうかの兆候は見つかりませんでした。

基本スキーマを想像してくださいthings:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "url": {
            "id": "url",
            "type": "string",
            "format": "uri"
        },
        "name": {
            "id": "name",
            "type": "string"
        }
    },
    "required": ["name"]
}

の両方のプロパティを再利用する、より具体的なpersonスキーマが必要な場合は、次のthingようにします。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "url": {
            "$ref": "http://example.com/thing.json#/properties/url",
        },
        "name": {
            "$ref": "http://example.com/thing.json#/properties/name",
        },
        "gender": {
            "id": "gender",
            "type": "string",
            "enum": ["F", "M"]
        },
        "nationality": {
            "id": "nationality",
            "type": "string"
        },
        "birthDate": {
            "id": "birthDate",
            "type": "string",
            "format": "date-time"
        }
    },
    "required": ["gender"]
}

ただし、このアプローチには 2 つの問題があります。

  1. 超定義が更新されると、依存スキーマも更新する必要があります
  2. これらすべての参照を手動で維持するのは面倒/冗長になります
  3. ルール ( などrequired: name) は、参照された定義の一部ではありません

単一のグローバル参照を使用して、次の効果的なJSON スキーマを取得する方法はありますか?

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "url": {
            "id": "url",
            "type": "string",
            "format": "uri"
        },
        "name": {
            "id": "name",
            "type": "string"
        }
        "gender": {
            "id": "gender",
            "type": "string",
            "enum": ["F", "M"]
        },
        "nationality": {
            "id": "nationality",
            "type": "string"
        },
        "birthDate": {
            "id": "birthDate",
            "type": "string",
            "format": "date-time"
        }
    },
    "required": ["name", "gender"]
}

$ref次のように、スキーマのルートに含めてみました。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://jsonschema.net/thing/person",
    "type": "object",
    "additionalProperties": false,
    "$ref": "http://example.com/thing.json",
    "properties": {
        "gender": {/* ... */},
        "nationality": {/* ... */},
        "birthDate": {/* ... */}
    },
    "required": ["gender"]
}

これには、プロパティを継承する効果がありthingますが、追加のプロパティはすべて無視されます。

gender: Additional property gender is not allowed
nationality: Additional property nationality is not allowed
birthDate: Additional property birthDate is not allowed
4

1 に答える 1

5

allOfキーワードを探しています。JSON スキーマは、私たちの多くが慣れ親しんでいるような継承を行いません。代わりに、データが親スキーマ (もの) と子スキーマ (人) の両方に対して有効である必要があることを伝えることができます。

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing.json",
    "type": "object",
    "properties": {
        "url": {
            "id": "url",
            "type": "string",
            "format": "uri"
        },
        "name": {
            "id": "name",
            "type": "string"
        }
    },
    "required": ["name"]
}

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "allOf": [
        { "$ref": "http://example.com/thing.json" },
        {
            "type": "object",
            "properties": {
                "gender": {
                    "id": "gender",
                    "type": "string",
                   "enum": ["F", "M"]
                },
                "nationality": {
                    "id": "nationality",
                    "type": "string"
                },
                "birthDate": {
                    "id": "birthDate",
                    "type": "string",
                    "format": "date-time"
                }
            },
            "required": ["gender"]
        }
    ],
}

または、私が好むように、より簡潔に次のように書きます

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "id": "http://example.com/thing/person.json",
    "allOf": [{ "$ref": "http://example.com/thing.json" }],
    "properties": {
        "gender": {
            "id": "gender",
            "type": "string",
            "enum": ["F", "M"]
        },
        "nationality": {
            "id": "nationality",
            "type": "string"
        },
        "birthDate": {
            "id": "birthDate",
            "type": "string",
            "format": "date-time"
        }
    },
    "required": ["gender"]
}

このアプローチを使用すると、 を使用できないことに注意してください"additionalProperties": false。このような理由から、追加のプロパティを明示的に禁止するのではなく、無視することをお勧めします。

于 2016-01-14T01:53:21.697 に答える