使用Python XML库解析XML遇unclosed token错误,求容错处理方案
解决XML解析时的"unclosed token"错误及无效XML处理方案
1. 捕获错误并跳过无效XML(基于标准库)
直接针对ET.ParseError做精准捕获,避免宽泛的exception掩盖其他问题,处理DataFrame时可以用apply批量处理,标记无效行后继续处理有效数据。
import pandas as pd from xml.etree import ElementTree as ET def parse_xml(xml_str): try: root = ET.fromstring(xml_str) emp = root.findall(".//employees") # 返回你需要的处理结果,比如提取员工相关字段 return [elem.text for elem in emp] except ET.ParseError: # 无效XML返回None,后续可过滤或标记 return None # 假设你的DataFrame是df,存储XML的列名为xml_col df['parsed_result'] = df['xml_col'].apply(parse_xml) # 过滤出解析成功的行继续处理 valid_records = df[df['parsed_result'].notna()]
2. 使用lxml的恢复模式修复无效XML
如果不想跳过无效XML,lxml的解析器支持recover=True模式,能自动修复未闭合标签、属性引号缺失等常见语法错误,是处理残缺XML的可靠方案。首先安装依赖:pip install lxml,然后实现代码:
import pandas as pd from lxml import etree def parse_xml_with_recover(xml_str): try: # 开启恢复模式的解析器 parser = etree.XMLParser(recover=True) # 注意需将字符串编码为字节流传入 root = etree.fromstring(xml_str.encode('utf-8'), parser=parser) # 用xpath查找节点,用法和ET的findall类似 emp_nodes = root.xpath(".//employees") return [node.text for node in emp_nodes] except Exception: # 极端无效的XML仍可能报错,捕获后返回None return None df['parsed_result'] = df['xml_col'].apply(parse_xml_with_recover)
3. 简单预处理修复未闭合标签(仅限特定场景)
如果不想引入lxml依赖,可针对"unclosed token"问题做极简预处理,但这种方法仅适用于简单的未闭合标签场景,复杂嵌套错误无法处理:
import pandas as pd from xml.etree import ElementTree as ET import re def fix_unclosed_tags(xml_str): # 提取所有非自闭合的开启标签 open_tags = re.findall(r'<([a-zA-Z0-9_]+)(?!/)>', xml_str) # 提取所有闭合标签 close_tags = re.findall(r'</([a-zA-Z0-9_]+)>', xml_str) # 找出未闭合的标签(这里简单取最后一个未闭合的标签补全) unclosed = [tag for tag in open_tags if tag not in close_tags] if unclosed: xml_str += f'</{unclosed[-1]}>' return xml_str def parse_xml_with_fix(xml_str): try: fixed_xml = fix_unclosed_tags(xml_str) root = ET.fromstring(fixed_xml) emp = root.findall(".//employees") return [elem.text for elem in emp] except ET.ParseError: return None df['parsed_result'] = df['xml_col'].apply(parse_xml_with_fix)
内容的提问来源于stack exchange,提问作者Bab
相关产品推荐
相关产品推荐

