Python JSON Schema校验失败:如何获取错误节点路径?
解决F5 AS3 JSON Schema校验无法获取错误节点路径的问题
问题场景
本地JSON文件与F5官方AS3 Schema校验时,正常校验功能正常,但当JSON存在错误(例如将declaration的class值从ADC改为ADC1),仅返回“不符合任一给定Schema”的模糊提示,无法通过e.path或e.json_path获取具体错误节点的路径(如.declaration.class)。
测试用错误JSON
{ "schema": "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/master/schema/latest/as3-schema.json", "class": "AS3", "action": "deploy", "persist": true, "declaration": { "class": "ADC1", "schemaVersion": "3.40.0", "target": { "hostname": "test.test.com" }, "id": "version_21.0", "label": "211008", "remark": "CO_version_21.0" } }
原校验脚本
import json import requests from jsonschema import Draft7Validator, ValidationError def load_json_from_url(url): response = requests.get(url) return response.json() def main(): schema_url = 'https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/master/schema/latest/as3-schema.json' schema = load_json_from_url(schema_url) schema['$id'] = schema['$id'].replace('urn:uuid:', '') with open('gtm1.json', 'r') as f: validJson = json.load(f) validator = Draft7Validator(schema) try: validator.validate(validJson) print('The JSON file is valid according to the schema.') except ValidationError as e: message = e.schema["error_msg"] if "error_msg" in e.schema else e.message print(f'Invalid data: {message}') if __name__ == '__main__': main()
解决方案
核心原因
F5 AS3 Schema大量使用oneOf/anyOf复合校验规则,校验失败时顶层ValidationError仅会提示整体不符合任一Schema,具体错误细节(含节点路径)被存储在e.context属性的子错误对象中。
修改后校验脚本
修改异常处理逻辑,遍历子错误获取具体路径和信息:
import json import requests from jsonschema import Draft7Validator, ValidationError def load_json_from_url(url): response = requests.get(url) return response.json() def main(): schema_url = 'https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/master/schema/latest/as3-schema.json' schema = load_json_from_url(schema_url) schema['$id'] = schema['$id'].replace('urn:uuid:', '') with open('gtm1.json', 'r') as f: validJson = json.load(f) validator = Draft7Validator(schema) try: validator.validate(validJson) print('The JSON file is valid according to the schema.') except ValidationError as e: # 处理无嵌套错误的情况 if not e.context: message = e.schema["error_msg"] if "error_msg" in e.schema else e.message print(f'Invalid data: {message}') else: # 遍历所有子错误,输出节点路径和错误详情 print("Validation errors found:") for idx, err in enumerate(e.context, 1): error_path = err.json_path # 如 .declaration.class error_msg = err.message print(f"{idx}. Path: {error_path}, Error: {error_msg}") if __name__ == '__main__': main()
测试效果
针对ADC1的错误,运行后会输出:
Validation errors found: 1. Path: .declaration.class, Error: 'ADC1' is not one of ['ADC', 'ADC_F5']
直接定位到错误节点,并明确错误原因。
内容的提问来源于stack exchange,提问作者sundrys1
相关产品推荐
相关产品推荐

