如何在不删除JSON Schema中的$id的情况下避免破坏$ref?

kninwzqo  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(66)

下面的JSON Schema中存在$id字段,当我尝试使用python中的jsonref库调用jsonschema.validate时,会导致jsonschema.exceptions._WrappedReferencingError

{
      "$schema": "http://json-schema.org/draft-07/schema#",
      "definitions": {
        "first_definition": {
          "value": "this is definitions/first_definition"
        },
        "second_definition": {
          "$id": "any_value",
          "properties": {
            "sections": {
              "$ref": "#/definitions/first_definition"
            }
          }
        }
      },
      "$ref": "#/definitions/second_definition"
    }

字符串
显然,有一个$id改变了$ref可以看到的范围?失败的$ref是'/definitions/first_definition' ref,WrappedReferencingError持有引用.exceptions. PointerToNowhere '。我可以删除$id来摆脱错误,但这似乎是错误的解决方案。有没有一种方法仍然有一个$id,但不破坏$ref?

tpgth1q7

tpgth1q71#

为什么你认为你需要$id?我只是好奇,如果你认为有用例,你相信它解决了。
$id充当作用域机制。它是模式的标识符。本质上,它只是创建该模式的新“文件”。因此使用#/definitions/first_definition意味着它在any_value模式根中查找first_definition
你可以这样想

根模式

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "first_definition": {
      "value": "this is definitions/first_definition"
    },
    "second_definition": {
      "$id": "any_value",
      "properties": {
        "sections": {
          "$ref": "#/definitions/first_definition"
        }
      }
    }
  },
  "$ref": "#/definitions/second_definition"
}

字符串

any_value架构。

first_definition未在此模式中定义,因此它不会解析为任何内容,从而引发错误

{
  "$id": "any_value",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "sections": {
      "$ref": "#/definitions/first_definition"
    }
  },
  "definitions": {}
}


当您删除$id时,它会将#/definitions/...的作用域更改为原始模式的根,并在其中找到已定义的first_definintion的定义。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "first_definition": {
      "value": "this is definitions/first_definition"
    },
    "second_definition": {
      "properties": {
        "sections": {
          "$ref": "#/definitions/first_definition"
        }
      }
    }
  },
  "$ref": "#/definitions/second_definition"
}


如果您真的想使用$id,您需要给予根模式一个id来引用,然后您就可以解析引用了。

{
  "$id": "root_schema",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "first_definition": {
      "value": "this is definitions/first_definition"
    },
    "second_definition": {
      "$id": "any_value",
      "properties": {
        "sections": {
          "$ref": "root_schema#/definitions/first_definition"
        }
      }
    }
  },
  "$ref": "#/definitions/second_definition"
}


id引用的另一种方法是使用相对或绝对文件路径引用。
假设文件名为root.schema.json。这将解析为文件路径,并且架构的根目录将通过#可用,这允许您在文件中导航。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "first_definition": {
      "value": "this is definitions/first_definition"
    },
    "second_definition": {
      "$id": "any_value",
      "properties": {
        "sections": {
          "$ref": "./root.schema.json#/definitions/first_definition"
        }
      }
    }
  },
  "$ref": "#/definitions/second_definition"
}

相关问题