allOf 项的 属性 是否可以包含指向另一个 allOf 项定义的 $ref?

Can a property of an allOf item contain a $ref to another allOf items definition?

"#/allOf/1/properties/body/properties/foo" 是有效的 $ref 吗?
正如解释 $ref 用法的 in this article 所述,看起来应该如此。
然而,AJV and https://www.jsonschemavalidator.net/ 似乎都不同意。

尝试使用普通的 JSON 指针似乎绝对可行:https://repl.it/repls/WretchedSpiritedMammoth

这是我正在测试的模式。

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "type": "object",
  "allOf": [
    {
      "$schema": "http://json-schema.org/draft-06/schema#",
      "$id": "http:/example.org/example.schema.json",
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "body": {
          "type": "object"
        }
      },
      "required": [
        "type",
        "body"
      ]
    },
    {
      "properties": {
        "body": {
          "$schema": "http://json-schema.org/draft-06/schema#",
          "$id": "http://example.org/foo.schema.json",
          "type": "object",
          "properties": {
            "foo": {
              "type": "number",
              "minimum": 1
            },
            "bar": {
              "$ref": "#/allOf/1/properties/body/properties/foo"
            }
          },
          "required": [
            "foo",
            "bar"
          ]
        }
      }
    }
  ]
}

编辑:这些是我得到的错误:

jsonschemavalidator.net

Error parsing schema
Message: Error when resolving schema reference '#/allOf/1/properties/body/properties/foo'. Path 'allOf[1].properties.body.properties.bar', line .., position ..

AJV:

can't resolve reference #/allOf/1/properties/body/properties/foo from id http://example.org/foo.schema.json"

尽管您在子架构中设置了 $id,但您的架构基本正确。

The "$id" keyword defines a URI for the schema, and the base URI that other URI references within the schema are resolved against.

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00#section-9.2

通过将 $id 添加到子架构,您已经为其他 URI 引用重置了基本 URI,其中包括在子架构及其子架构中对 $ref 的任何使用。

$ref

...Resolved against the current URI base, it identifies the URI of a schema to use.

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00#section-8

将 bar 的定义更改为以下内容,您的模式将有效。

"bar": {
  "$ref": "#/properties/foo"
}

根据 Relequestual 在他后来的评论中的要求进一步编辑:

将绝对 URI 作为子模式 $id 是有效的,但如前所述,它会重置基本 URI。 $id 值的限制仅适用于使用它来创建本地 URI 片段标识符(如果这对您没有任何意义,请不要担心)。

直接从另一个 属性 模式引用 属性 模式是有效的,但更常见的最佳做法是将这样的模式放在“定义”关键字下,并让两个属性都引用它地点。这是我推荐的最大清晰度:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "type": "object",
  "allOf": [
    {
      "$schema": "http://json-schema.org/draft-06/schema#",
      "$id": "http:/example.org/example.schema.json",
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "body": {
          "type": "object"
        }
      },
      "required": [
        "type",
        "body"
      ]
    },
    {
      "properties": {
        "body": {
          "$schema": "http://json-schema.org/draft-06/schema#",
          "$id": "http://example.org/foo.schema.json",
          "type": "object",
          "properties": {
            "foo": {
              "$ref": "#/definitions/whateverYouWantToCallIt"
            },
            "bar": {
              "$ref": "#/definitions/whateverYouWantToCallIt"
            }
          },
          "required": [
            "foo",
            "bar"
          ]
        }
      },
      "definitions": {
        "whateverYouWantToCallIt": {
          "type": "number",
          "minimum": 1
        }
      }
    }
  ]
}