You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:02:13