Json 如何引用在另一个模式中定义的内部对象而不显式指定整个路径

Json 如何引用在另一个模式中定义的内部对象而不显式指定整个路径,json,jsonschema,Json,Jsonschema,我有以下文件: A.json { "B": { "level1": { "abc": "123" } } } ASchema.json { "$id": "ASchema.json", "$schema": "http://json-schema.org/draft-07/schema#", "properties": { "B": { "allOf": [ { "$ref": "BSche

我有以下文件:

A.json

{
  "B": {
    "level1": {
      "abc": "123"
    }
  }
}
ASchema.json

{
  "$id": "ASchema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "B": {
      "allOf": [
        {
          "$ref": "BSchema.json#/definitions/B"
        },
        {
          "properties": {
            "level1": {
              "properties": {
                "abc": {
                  "enum": [
                    "123"
                  ]
                }
              }
            }
          }
        }
      ]
    }
  },
  "type": "object"
}
{
  "$id": "BSchema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "B": {
      "$id": "#/definitions/B",
      "type": "object",
      "required": [
        "level1"
      ],
      "properties": {
        "level1": {
          "$id": "#/definitions/B/properties/level1",
          "type": "object",
          "required": [
            "abc"
          ],
          "properties": {
            "abc": {
              "$id": "#/definitions/B/properties/level1/properties/abc",
              "type": "string"
            }
          }
        }
      }
    }
  }
}
BSchema.json

{
  "$id": "ASchema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "B": {
      "allOf": [
        {
          "$ref": "BSchema.json#/definitions/B"
        },
        {
          "properties": {
            "level1": {
              "properties": {
                "abc": {
                  "enum": [
                    "123"
                  ]
                }
              }
            }
          }
        }
      ]
    }
  },
  "type": "object"
}
{
  "$id": "BSchema.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "B": {
      "$id": "#/definitions/B",
      "type": "object",
      "required": [
        "level1"
      ],
      "properties": {
        "level1": {
          "$id": "#/definitions/B/properties/level1",
          "type": "object",
          "required": [
            "abc"
          ],
          "properties": {
            "abc": {
              "$id": "#/definitions/B/properties/level1/properties/abc",
              "type": "string"
            }
          }
        }
      }
    }
  }
}
我想为ASchema.json中的内部对象(BSchema.json中的B.level1.abc)添加一个约束,而无需像上面示例中那样显式键入完整路径:

"properties": {
  "level1": {
    "properties": {
      "abc": {
        "enum": [
          "123"
        ]
      }
    }
  }
}
有没有办法通过id引用内部对象?类似于:

{
  "$ref": {
    "BSchema.json#/definitions/B/properties/level1/properties/abc",
    "enum": [ "123" ]
  }
}

经过对松弛的讨论,我对你的问题理解得更清楚了。 您希望能够直接引用另一个模式的一部分,而不需要完整路径

要使用JSON模式draft-7实现这一点,必须使用命名的$id

让我解释一下这个模式中发生了什么

我已经简化了你的例子,将BSchema加入(或排除)到一个定义中。在本例中,该定义的关键点是什么并不重要,只是它位于有效的子模式位置

子模式的完整URI
$id
http://example.com/BSchema.json
。这将在评估该树中的子模式时重置基本URI

在BSchema属性中,我们将
level1
定义为$id为`#level'。这类似于HTML元素中的id属性

为了简化示例,只需将level1设置为
false
,即可使演示的模式验证失败

定义之后,我们引用
BSchema.json#level
。请注意,不要选择“level1”,以便可以更改属性名称


解析是通过查看模式的基本URI(在本例中是根模式)并使用URI解析规则来确定正确的URI
http://example.com/BSchema.json
。接下来,URI的片段就是目标,可以在BSchema模式中找到。

我写了一个答案,然后意识到我看错了你的问题。可以,但不应该,因为在某些情况下,实现之间的行为是不一致的。我们在2019-09草案中创建了一个新的关键字($anchor),专门用于此目的,同时指定使用
$id
执行此操作的行为不可靠或始终不受支持。这是一个令人困惑和棘手的话题。。。这是我在这篇评论中无法表达的。如果您想了解更多,请随时加入我们的(JSON模式)社区。这里没有速记。JSON模式很棒,但有时可能会很冗长。这是其中一次。