多阶段 $ref 不适用于 jsonschema 版本 3.0.1

Multi-stage $ref doesn't work with jsonschema version 3.0.1

似乎 jsonschema 版本 3.0.1 不接受使用 $refs 的多阶段模式(但它适用于 jsonschema 版本 2.6.0)。

我必须让它在多个模块版本下工作,因为我的代码将 运行 在具有不同环境的不同计算机上。

我在 https://www.jsonschemavalidator.net/ 上验证了我的 json(感谢 link 在另一个 Whosebug 问题中找到的)。

我试过了:

  jsonschema -i myjson.json noRefs.schema.json      --> 2.6.0 = OK, 3.0.1 OK
  jsonschema -i myjson.json usingRefs.schema.json   --> 2.6.0 = OK, 3.0.1 KO

注意: *.schema.json 都在 https://www.jsonschemavalidator.net/

上工作

文件myjson.json:

{
  "TopProperty" : {
    "LowerProperty" : {"toto" : "plop"}
  }
}

文件编号。schema.json :

{
  "type": "object",

  "properties": {
    "TopProperty": {"$ref": "#/schemaTopProperty"}
  },

  "schemaTopProperty": {
    "$id": "schemaTopProperty",
    "type": "object",

    "properties": {
      "LowerProperty": {
        "type": "object",
        "properties": {
          "toto": {"type": "string"}
        }
      }
    }
  }
}

文件使用引用。schema.json :

{
  "type": "object",

  "properties": {
    "TopProperty": {"$ref": "#/schemaTopProperty"}
  },

  "schemaTopProperty": {
    "$id": "schemaTopProperty",
    "type": "object",

    "properties": {
      "LowerProperty": {
        "type": "object",
        "properties": {
          "toto": {"$ref": "#/justAString"}
        }
      }
    }
  },

  "justAString": {
    "$id": "justAString",
    "type": "string"
  }

}

收到错误消息:

Traceback (most recent call last):                                                                                                         
  File "/usr/bin/jsonschema", line 11, in <module>                                                                                         
    sys.exit(main())                                                                                                                       
  File "/usr/lib/python2.7/site-packages/jsonschema/cli.py", line 67, in main                                                              
    sys.exit(run(arguments=parse_args(args=args)))                                                                                         
  File "/usr/lib/python2.7/site-packages/jsonschema/cli.py", line 78, in run                                                               
    for error in validator.iter_errors(instance):                                                                                          
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors                                               
    for error in errors:                                                                                                                   
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 274, in properties                                               
    schema_path=property,                                                                                                                  
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 339, in descend                                                   
    for error in self.iter_errors(instance, schema):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors
    for error in errors:
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 251, in ref
    for error in validator.descend(instance, resolved):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 339, in descend
    for error in self.iter_errors(instance, schema):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors
    for error in errors:
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 274, in properties
    schema_path=property,
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 339, in descend
    for error in self.iter_errors(instance, schema):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors
    for error in errors:
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 73, in items
    for error in validator.descend(item, items, path=index):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 339, in descend
    for error in self.iter_errors(instance, schema):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors
    for error in errors:
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 274, in properties
    schema_path=property,
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 339, in descend
    for error in self.iter_errors(instance, schema):
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 323, in iter_errors
    for error in errors:
  File "/usr/lib/python2.7/site-packages/jsonschema/_validators.py", line 247, in ref
    scope, resolved = validator.resolver.resolve(ref)
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 734, in resolve
    return url, self._remote_cache(url)
  File "/usr/lib/python2.7/site-packages/functools32/functools32.py", line 400, in wrapper
    result = user_function(*args, **kwds)
  File "/usr/lib/python2.7/site-packages/jsonschema/validators.py", line 744, in resolve_from_url
    raise exceptions.RefResolutionError(exc)
jsonschema.exceptions.RefResolutionError: unknown url type: schemaTopProperty

编辑:我之前的回答不正确。

TL;DR:您有两个选择:

  1. 从定义中删除 $id 属性
  2. $id 属性中使用 #/(示例:{"$id": "#/justAString"}

详情:

问题在于 ID,直到 draft-04,$ref$id 都按表面值处理,没有什么特别的,但从 draft-06 开始,这些是 uri-references,在这种情况下,当下降到 {"$id": "schemaTopProperty"} 时,解析 {"$ref": "justAString"} 不再是在根结构中寻找片段 justAString,而是在 [=21] 下寻找 /justAString =] host,这是一个远程引用。

因此,我的解决方案是删除导致定义为 URL(实际上是主机)的 $id,或者将 $id 定义为当前的片段架构。