xml.etree.elementtree适合解析结构清晰的xml,需注意编码、空值处理、字段映射及markdown转义;避免模糊xpath,统一用(text or '').strip()取值,表头与分隔行需规范生成。

XML 解析用 xml.etree.ElementTree 最轻量
Python 自带的 xml.etree.ElementTree 足够应付绝大多数结构清晰的 XML 表格数据(比如配置导出、简单报表),不用装第三方库。它不支持 DTD 或命名空间复杂的 XML,但如果你的 XML 是类似 <row><col1>A</col1><col2>B</col2></row> 这种扁平结构,直接上手就行。
常见错误现象:ParseError: not well-formed (invalid token) —— 多半是 XML 里混了未转义的 &、、<code>>,或编码不是 UTF-8(尤其 Windows 记事本保存的 XML 常带 BOM)。先用文本编辑器确认编码,再用 open(... , encoding='utf-8') 显式指定。
- 优先用
ET.parse()加载文件;若内容来自字符串,用ET.fromstring() - 避免用
findall('.//row')这种模糊路径——性能差,且容易漏掉嵌套层级变化的 case - 列名建议从首行
<row></row>的子节点 tag 推断,别硬编码['name', 'age', 'city'],否则 XML 字段一变脚本就挂
提取字段时别直接取 .text,要处理空值和换行
XML 里的 <age></age> 或 <city></city>,用 elem.text 会得到 None;而 <note>
hello
</note> 会带前后空白和换行。Markdown 表格里塞 None 或缩进空格,渲染出来就是错位或空格乱码。
使用场景:你拿到的 XML 可能由不同系统导出,有的字段留空用自闭合标签,有的用空标签,有的干脆缺失节点。
- 统一用
(elem.text or '').strip()获取内容 - 如果某列必须有值,但 XML 中可能缺失,用
elem.find('col_name') or elem.find('.//col_name')再判空,别假设层级固定 - 表格中禁止出现
|、\、^等 Markdown 表格分隔符,提前用.replace('|', '\|').replace(' ', ' ')简单转义
生成 Markdown 表格头和分隔行有固定写法
Markdown 表格不是靠缩进或空格对齐,而是靠 | 分隔 + 第二行用 |---|---| 定义对齐方式。很多人手写时漏掉第二行,或在分隔行里混用 : 导致解析失败。
性能影响:表头和分隔行只需生成一次,不要在循环里重复拼接;字段名数量大时(比如 50+ 列),用 ['|'] + [f' {h} ' for h in headers] + ['|'] 比字符串 + 拼接快。
- 表头行:拼成
| col1 | col2 | col3 | - 分隔行:对应列统一用
|---|---|---|(左对齐);需要右对齐某列?写成|---:|;居中?|:-:| - 每行数据也必须以
|开头和结尾,中间每个字段用|隔开,字段内不能有未转义的|
中文字段名或含空格的 tag 名需映射为合法列名
XML 里常有 、<order date></order> 这类 tag,直接当表头会导致 Markdown 渲染异常(空格破坏分隔逻辑,中文本身没问题但可读性差),更麻烦的是后续想用 Pandas 处理时字段名不合法。
容易踩的坑:有人用正则删所有非字母数字,结果 user_id 和 userid 全变成 userid,冲突了。
- 建议做最小映射:空格 →
_,中文 → 直接保留(Markdown 表格支持),特殊符号如@、.→_ - 加个去重逻辑:如果两个 tag 映射后相同(如
<user id></user>和<user_id></user_id>都变user_id),在后面追加序号user_id_1、user_id_2 - 这个映射最好单独抽成函数,调试时打印原始 tag → 映射名对照表,比盲猜靠谱
真正麻烦的不是解析 XML,是 XML 结构不一致——同一份 XSD 下,某次导出多了一层 <data><rows><row></row></rows></data>,下次又扁平成 <row></row>。别指望一个脚本永远通用,每次换数据源前,先 print(ET.tostring(root, encoding='unicode')[:200]) 看一眼顶层结构。










