0

我正在尝试定义一个有效的 JSON 模式,但当被引用的组件位于子目录中时,我不确定如何构造引用 ("$ref") 值。我已经(详细地)阅读了官方 JSON Schema 站点上的信息,并检查了来自各种 JSON Schema 解析器的测试数据,但是可用的信息要么不清楚要么不可用(或者,当然,我找不到它尽管搜索了几个小时)...

我需要的具体帮助是确认组件目录中文件的引用(引用组件目录中的文件)是否应该在引用中用“组件”定义。(请注意,$id 不可用于提供基本 URI)。

换句话说,“message.schema.json”中的引用应该是:

  • 选项 1:“components/key.schema.json”和“components/data.schema.json”,或者,
  • 选项2:“key.schema.json”和“data.schema.json”(如下图)

在选项 1 中,“$ref”相对于父路径(“main.schema.json”),在选项 2 中,它相对于当前路径(“message.schema.json”)。

以下是提供进一步背景的信息。

文件结构比较简单,如下图所示:

main.schema.json
  - message.schema.json
  - key.schema.json
  - data.schema.json

文件内容如下所示...

main.schema.json:

{
  "$id": "https://example.com/arrays.schema.json",
  "description": "main.schema.json",
  "type": "object",
  "required": [ "messages" ],
  "properties": {
    "messages": {
      "type": "array",
      "items": { "$ref": "components/message.schema.json" }
    }
  }
}

上面的 JSON Schema 引用了“components”目录(main.schema.json 文件下的一个目录)中的文件。

message.schema.json:

{
  "$id": "https://example.com/arrays.schema.json",
  "description": "message.schema.json",
  "type": "object",
  "required": [ "message" ],
  "properties": {
    "message": {
      "type": "object",
      "required": [ "key", "data" ],
      "properties": {
        "key": {
          "$ref": "key.schema.json"
        },
        "data": {
          "$ref": "data.schema.json"
        }
      }
    }
  }
}

并且上面的 message.schema.json 引用了与 message.schema.json 文件位于同一目录中的以下组件:

key.schema.json:

{
  "$id": "https://example.com/arrays.schema.json",
  "description": "key.schema.json",
  "type": "object",
  "required": [ "key" ],
  "properties": {
    "key": {
      "type": "string"
    }
  }
}

数据.schema.json:

{
  "$id": "https://example.com/arrays.schema.json",
  "description": "data.schema.json",
  "type": "object",
  "required": [ "data" ],
  "properties": {
    "data": {
      "type": "object",
      "required": [ "veggieName", "veggieLike" ],
      "properties": {
        "veggieName": {
          "type": "string",
          "description": "The name of the vegetable."
        },
        "veggieLike": {
          "type": "boolean",
          "description": "Do I like this vegetable?"
        }
      }
    }
  }
}
4

1 回答 1

0

为什么你所有的模式都有相同的$id?许多实现会在这方面出错,或者导致它们在您加载具有相同标识符的稍后模式时“忘记”早期模式。

我不确定您是否认为description这里使用了关键字,但事实并非如此。重要的关键字是$id,它的值用作未来 URI 解析的基础,例如$ref.

根据您使用的特定实现,您需要确保$id关键字中的 URI 可以正确解析(也就是说,如果您转到 URL“https://example.com/message.schema.json”它实际上会下载一些东西),或者您需要在开始评估之前手动将所有文件加载到实现中。规范并不要求实现支持网络解析,但它们需要支持某种机制,以便在其规范标识符下预加载模式。

如果您将这些值用作$ids(将 example.com 替换为更合适的主机):

..那么从 main 到其他文件的所有引用都可以通过 uri 引用进行:

  • 从主要文件到其他文件:"$ref": "components/key.schema.json"
  • 从其他文件到彼此:"$ref": "key.schema.json"
  • 从其他文件回到主文件:"$ref": "../main.schema.json"

当然,您也可以在所有$refs 中使用完整的绝对 URI。

于 2021-11-04T22:31:21.953 回答