使用模式列表进行Python JSON模式验证

3
我正在尝试使用Python和jsonschema模块根据模式验证JSON文件。我的模式是由一系列模式组成的列表,其中一个模式包含基本元素的定义,其余模式则包含这些元素和其他对象的集合。
我找不到加载模式列表的函数文档,以便可以使用它进行验证。我试图将模式分成字典,并在jsonObject上调用适当的模式,但由于它们互相引用,所以这样做不起作用。
如何加载/组装所有模式以进行验证?
我正在尝试加载的模式的一部分:
[{
    "definitions": {
     "location": {
       "required": [
         "name",
         "country"
       ],
       "additionalProperties": false,
       "properties": {
         "country": {
           "pattern": "^[A-Z]{2}$",
           "type": "string"
         },
         "name": {
           "type": "string"
         }
       },
       "type": "object"
      }
    },
    "required": [
       "type",
       "content"
    ],
    "additionalProperties": false,
    "properties": {
     "content": {
      "additionalProperties": false,
      "type": "object"
     },
     "type": {
      "type": "string"
     }
    },
    "type": "object",
    "title": "base",
    "$schema": "http://json-schema.org/draft-04/schema#"
  },
  {
    "properties": {
      "content": {
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "$ref": "#/definitions/location"
        }
      },
      "type": {
        "pattern": "^person$"
      }
    }
  }]

JSON对象大概长这样:

{
 "type":"person",
 "content":{
  "address": {
   "country": "US",
   "name" : "1,Street,City,State,US"
  }
 }
}
2个回答

3
您一次只能针对一个模式进行验证,但该模式可以引用($ref)外部模式。这些引用通常是可用于获取模式的URI。如果您的模式不是公共的,则可能也可以使用文件路径。使用您示例的固定版本,它应该如下所示... http://your-domain.com/schema/person
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Person",
  "allOf": [{ "$ref": "http://your-domain.com/schema/base#" }],
  "properties": {
    "type": { "enum": ["person"] },
    "content": {
      "properties": {
        "address": { "$ref": "http://your-domain.com/schema/base#/definitions/location" }
      },
      "required": ["address"],
      "additionalProperties": false
    }
  }
}

http://your-domain.com/schema/base

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "base",
  "type": "object",
  "properties": {
    "content": { "type": "object" },
    "type": { "type": "string" }
  },
  "required": ["type", "content"],
  "additionalProperties": false,
  "definitions": {
    "location": {
      "type": "object",
      "properties": {
        "country": {
          "type": "string",
          "pattern": "^[A-Z]{2}$"
        },
        "name": { "type": "string" }
      },
      "required": ["name", "country"],
      "additionalProperties": false
    }
  }
}

以下是一些有用的文档


很遗憾,这个方案不是由我设定的。由于它在许多其他领域中被使用,我无法更改它,它目前存在于一个列表中。是否可能引用代码(Python)内存在变量中的方案? - Rizhiy
为了使验证器引用内存中的模式,您需要构建自己的“RefResolver”来定义自定义行为,并将其插入到验证器中。我链接的文档应该会指引您正确的方向。 - Jason Desrosiers
就基于架构列表进行验证而言,你无法这样做。那不是一个有效的模式。最好的做法是独立验证每个模式,并确保没有一个失败。然而,由于在内容属性中使用了“additionalProperties”,这两个模式都永远无法同时验证通过。其中一个要求对象为空,而另一个要求对象具有“address”属性。这些是互斥的条件。 - Jason Desrosiers
如果这个模式列表在许多其他领域中被使用,您能否看到它在这些情况下是如何被使用的,并采取类似的措施? - Jason Desrosiers
是的,最终我问了写这个代码的人,他说我只需要编写一个函数,从列表中构建一个单一的方案。 - Rizhiy

0

不必手动编写一个包含所有模式的单个模式,您可以创建一个小模式,该模式引用其他模式文件。这样,您就可以使用多个现有的JSONschema文件,并组合验证它们:

import yaml
import jsonschema

A_yaml = """
id: http://foo/a.json
type: object
properties: 
    prop: 
        $ref: "./num_string.json"
"""

num_string_yaml = """
id: http://foo/num_string.json
type: string
pattern: ^[0-9]*$
"""

A = yaml.load(A_yaml)
num_string = yaml.load(num_string_yaml)

resolver = jsonschema.RefResolver("",None,
        store={
            "http://foo/A.json":A,
            "http://foo/num_string.json":num_string,
            })

validator = jsonschema.Draft4Validator(
        A, resolver=resolver)

try:
    validator.validate({"prop":"1234"})
    print "Properly accepted object"
except jsonschema.exceptions.ValidationError: 
    print "Failed to accept object"

try:
    validator.validate({"prop":"12d34"})
    print "Failed to reject object"
except jsonschema.exceptions.ValidationError: 
    print "Properly rejected object"

请注意,您可能希望使用模式组合器之一oneOfallOfanyOf来组合您的模式,如下所示:
[A.yaml]
oneOf:
     - $ref: "sub-schema1.json"
     - $ref: "sub-schema2.json"
     - $ref: "sub-schema3.json"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接