【问题标题】:Multi-stage $ref doesn't work with jsonschema version 3.0.1多阶段 $ref 不适用于 jsonschema 版本 3.0.1
【发布时间】:2019-05-17 08:16:53
【问题描述】:

似乎 jsonschema 3.0.1 版不接受使用 $refs 的多阶段架构(虽然它适用于 jsonschema 2.6.0 版)。

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

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

我试过了:

  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"}
  }
}

文件 noRefs.schema.json :

{
  "type": "object",

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

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

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

文件使用Refs.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

【问题讨论】:

  • 关于什么是有效的引用对象存在争议。您是否尝试过将要引用的属性放入 definitions 对象中?假设这里是草稿 7。
  • link 之后,我尝试将我的 justAStringobject 嵌入到 definitions 中,但我收到了相同的错误消息。
  • 我已经简化了我的文件,希望它会更清晰。
  • 我使用jsonschema.dev 测试了您的架构,它似乎工作正常。看起来这是一个实施问题,您应该在实施问题跟踪器上记录一个问题。我已经通知作者我们的 slack 服务器上的实现,但我不能说他们什么时候会回复。
  • 感谢您的测试。我在google forum 上写了一篇文章。我也会看看 Slack。

标签: jsonschema python-jsonschema


【解决方案1】:

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

TL;DR:你有两个选择:

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

详情:

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

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

【讨论】:

  • 回到我的实际应用案例,删除$id 的解决方案立即奏效。第二个选项更棘手,它还没有工作。谢谢!
  • 我在第二个解决方案中添加了一个示例,不太清楚,抱歉。
  • 很明显不用担心。第二个选项工作正常,我错误地将#/ 也用于文件的$id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 2014-03-30
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 2013-08-11
相关资源
最近更新 更多