如何使用 JsonSchema 在不重复的情况下对复杂模式进行建模?

How to model complex schema without much repetition using JsonSchema?

我正在尝试对文档(例如护照)及其属性(名字、出生日期等)进行建模,并使用 json schema 来描述它们。

我想在运行时定义多种类型的文档,每个文档都作为一个单独的模式。 有些属性可能被多个文档引用,比如护照和驾照中的firstName,所以它是 为此创建一个单独的属性定义模式可能是明智的。

比方说,我有护照,它的型号如下:

{
  "owner":  "<string>",
  "type" :  "<string>",
  "salt" :  <number>,
  "attributes": {
    "number"     : {"value": "<string>",     "salt": <number>}
    "lastName"   : {"value": "<string>",     "salt": <number>},
    "firstName"  : {"value": "<string>",     "salt": <number>},
    "birthDate"  : {"value": "<date>",       "salt": <number>},
    "nationality": {"value": "<string>",     "salt": <number>},
  }
}

每个属性都有"value"和"salt",但是"value"对于每个键(属性名)都是不同的。 我的问题是,这种 JSON 文档的架构看起来如何?

UPD:每个属性都有valuesalt。 Salt 对于所有属性都是完全相等的,但是 value 是不同的。如果我手动指定每个属性都有 saltvalue,那么我最终会得到大量的模式重复。可以避免吗?

使用 JSON 架构的 draft-7(撰写本文时为当前版本),假设您要使用对包含 属性 定义的另一个文件的引用,您可能需要做类似下面的事情。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "number": {
      "properties": {
        "value": {...}, # Whatever you define as your schema for number/value.
        "salt": {
          "$ref": "externalRef/definitions/salt"
        }
      }
    }
  }
}

您可以做很多事情来减少模式中的重复。一种方法是使用 definitions 关键字。另一种选择是使用 patternProperties 来验证跨多个属性的公共约束。

{
  "type": "object",
  "properties": {
    "owner": { "type": "string" },
    "type": { "type": "string" },
    "salt": { "$ref": "#/definitions/salt" },
    "attributes": {
      "type": "object",
      "patternProperties": {
        ".*": {
          "type": "object",
          "properties": {
            "salt": { "$ref": "#/definitions/salt" }
          },
          "required": ["value", "salt"]
        }
      },
      "properties": {
        "number": { "$ref": "#/definitions/string-value" },
        "lastName": { "$ref": "#/definitions/string-value" },
        "firstName": { "$ref": "#/definitions/string-value" },
        "birthDate": { "$ref": "#/definitions/date-value" },
        "nationality": { "$ref": "#/definitions/string-value" }
      }
    }
  },
  "definitions": {
    "salt": { "const": 1234 },
    "string-value": {
      "properties": {
        "value": { "type": "string" }
      }
    },
    "date-value": {
      "properties": {
        "value": { "type": "string", "format": "date" }
      }
    }
  }
}