需要Python中JSON Schema验证的详细错误信息

-2 投票
1 回答
49 浏览
提问于 2025-04-13 16:56

我有一个 JSON 模式,我想用 Python 的一个库来验证输入的 JSON 是否符合这个模式。这个模式是使用 draft-08 版本,也就是 2019-09。所以我尝试了下面的代码,但它没有详细给出错误信息。例如,在提供的示例输入中,resending 的类型是布尔值,但代码却没有指出这一点,而是给出了一个模糊的错误信息,像是 <[{'entityType': 'default', 'function': '01', 'resending': 'False', 'afdDefinitionName': 'example', 'originalMessageId': '12345'}] 不符合给定模式>

模式:

{
    "$schema": "http://json-schema.org/draft/2019-09/schema#",
    "description": "my schema",
    "definitions": {
      "BCCI": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "entityType": {
            "description": "",
            "type": "string",
            "const": "default"
          },
          "function": {
            "description": "",
            "codelistName": "ADNFUN",
            "type": "string",
            "oneOf": [
              {
                "const": "01"
              },
              {
                "const": "02"
              },
              {
                "const": "09"
              },
              {
                "const": "54"
              }
            ]
          },
          "resending": {
            "description": "",
            "type": "boolean"
          },
          "afdDefinitionName": {
            "description": "",
            "customDescription": "",
            "type": "string"
          },
          "originalMessageId": {
            "description": "",
            "customDescription": "",
            "type": "string"
          }
        },
        "required": [
          "entityType",
          "function",
          "afdDefinitionName"
        ]
      }
    },
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "BCCI": {
        "type": "array",
        "uniqueItems": true,
        "allOf": [
          {
            "minContains": 1,
            "maxContains": 1,
            "contains": {
              "$ref": "#/definitions/BCCI"
            }
          }
        ]
      }
    },
    "required": [
      "BCCI"
    ]
  }

JSON 输入:

{
    "BCCI": [
        {
            "entityType": "default",
            "function": "01",
            "resending": "false",
            "afdDefinitionName": "example",
            "originalMessageId": "12345"
        }
    ]
}

使用的代码:

import json
import jsonschema
from jsonschema import validate, validators, Draft7Validator, Draft201909Validator, Draft202012Validator
from jsonschema.exceptions import ValidationError

json_file = 'path to json instance'
json_schema_file = 'path to json schema instance'

with open(json_file) as f:
    document = json.load(f)

with open(json_schema_file) as f:
    schema = json.load(f)

errors = []
try:
    validate(instance=document, schema=schema)
except jsonschema.exceptions.ValidationError as e:
    print("----------------------------------------------------------")
    print(e)
    print("----------------------------------------------------------")
    
    print(f"Error message: {e.message}")
    print(f"Error tag: {e.json_path}")
    print(f"Error tag: {list(e.path)}")
    print(f"Definition: {e.validator}")

输出:

----------------------------------------------------------
[{'entityType': 'default', 'function': '01', 'resending': 'false', 'afdDefinitionName': 'example', 'originalMessageId': '12345'}] does not contain items matching the given schema

Failed validating 'contains' in schema['properties']['BCCI']['allOf'][0]:
    {'contains': {'$ref': '#/definitions/BCCI'},
     'maxContains': 1,
     'minContains': 1}

On instance['BCCI']:
    [{'afdDefinitionName': 'example',
      'entityType': 'default',
      'function': '01',
      'originalMessageId': '12345',
      'resending': 'false'}]
----------------------------------------------------------
Error message: [{'entityType': 'default', 'function': '01', 'resending': 'false', 'afdDefinitionName': 'example', 'originalMessageId': '12345'}] does not contain items matching the given schema
Error tag: $.BCCI
Error tag: ['BCCI']
Definition: contains

它应该打印出关于布尔值的问题,或者如果输入的 JSON 有其他问题,但它没有给出详细的错误信息。

1 个回答

1

问题出在使用的关键词上,因为使用了draft-08版本中的不正确的关键词,所以没有给出详细的错误信息。请在你的架构中使用Items/minItems/maxItems,而不是contains/minContains/maxContains,这样你的代码就能正常工作了。下面是我正在使用的更新后的代码,它能详细列出某个特定json实例的所有错误。

import json
from jsonschema import  Draft201909Validator

json_file = 'test.json'
json_schema_file = 'test_schema.json'

with open(json_file) as f:
    document = json.load(f)

with open(json_schema_file) as f:
    schema = json.load(f)

v = Draft201909Validator(schema)

for rec in document:
    temp = rec.get("error", [])
    errors = sorted(v.iter_errors(rec), key=lambda e: e.path)
    for error in errors:
        print("---------------------------------------")
        print("json_path list:", list(error.path))
        print("error_message:", error.message)
        

更新后的json输入架构:

{
    "$schema": "http://json-schema.org/draft/2019-09/schema#",
    "description": "my schema",
    "definitions": {
      "BCCI": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "entityType": {
            "description": "",
            "type": "string",
            "const": "default"
          },
          "function": {
            "description": "",
            "codelistName": "XXXXXX",
            "type": "string",
            "oneOf": [
              {
                "const": "01"
              },
              {
                "const": "02"
              },
              {
                "const": "09"
              },
              {
                "const": "54"
              }
            ]
          },
          "resending": {
            "description": "",
            "type": "boolean"
          },
          "afdDefinitionName": {
            "description": "",
            "customDescription": "",
            "type": "string"
          },
          "originalMessageId": {
            "description": "",
            "customDescription": "",
            "type": "string"
          }
        },
        "required": [
          "entityType",
          "function",
          "afdDefinitionName"
        ]
      }
    },
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "BCCI": {
        "type": "array",
        "uniqueItems": true,
        "items": {
            "$ref": "#/definitions/BCCI"
          },
          "minItems": 1,
          "maxItems": 1
      }
    },
    "required": [
      "BCCI"
    ]
  }

撰写回答