Python使用jsonschema校验JSON时如何输出错误对应具体行号
实现方案
可行,核心原因是标准库json默认加载生成的原生Python字典/列表不会存储字段在源文件中的行号位置信息,因此需要在JSON加载阶段同步记录节点位置,再和校验返回的错误路径做匹配即可输出带行号的错误信息。
推荐实现(代码改动最小)
用ruamel.yaml库加载JSON(JSON是YAML的标准子集,该库解析JSON时会自动给每个节点绑定行号、列号属性),步骤如下:
- 安装依赖
pip install ruamel.yaml jsonschema
- 替换原有加载+校验逻辑
from ruamel.yaml import YAML from jsonschema import Draft7Validator # 替换为你实际使用的校验器版本即可 # 初始化JSON兼容的解析器 yaml_parser = YAML(typ="safe") yaml_parser.default_flow_style = True # 加载目标JSON文件,加载出的节点自带lc(行列位置)属性 with open("your_target.json", "r", encoding="utf-8") as f: jsonData = yaml_parser.load(f) # 递归根据错误路径查询对应行号 def fetch_line_num(node, error_path): current_node = node for path_seg in error_path: current_node = current_node[path_seg] # lc.line为0起始计数,+1后和编辑器显示的行号一致 return current_node.lc.line + 1 # 原有校验逻辑基本不变 validator = Draft7Validator(your_pre_defined_schema) # 替换为你预先编写的schema errors = sorted(validator.iter_errors(jsonData[a]), key=lambda e: e.path) for error in errors: try: line = fetch_line_num(jsonData[a], error.path) except AttributeError: # 根节点级别的错误默认定位到第1行 line = 1 print(f"On line number {line} ,{error.message}", sep=", ")
效果说明
- 普通字段类型错误、数组元素错误:可以精准定位到出错节点所在行
- 缺失必填字段的错误:会定位到缺失字段所属父对象的起始行,和实际字段位置误差不超过2行,足够用于问题定位
- 如果需要更精准的必填字段行号,可以额外判断错误类型为
required时,通过父节点的lc.key(缺失字段名)方法获取对应键的精确行号,从错误信息中提取缺失字段名做匹配即可
可选无额外依赖方案
如果不想安装第三方解析库,也可以基于标准库json模块的object_pairs_hook、array_hook参数自定义解析逻辑,在解析过程中手动记录每个JSON路径对应的行号,再和错误路径匹配。该方案代码量较大,需要处理嵌套对象、数组、转义字符等边界情况,日常使用优先选上述方案即可。
内容的提问来源于stack exchange,提问作者Montek
相关产品推荐
相关产品推荐

