xml转txt本质是提取文本节点而非格式转换,需用elementtree.itertext()或lxml.text_content()获取纯文字,注意编码、cdata及结构容错性。

XML转TXT本质是提取文本节点,不是格式转换
XML文件本身是文本,所谓“转成TXT”其实是把嵌套结构里的纯文字内容抽出来,丢掉标签、属性、注释这些非文本信息。直接重命名.xml为.txt只是改后缀,文件内容没变,浏览器或编辑器可能显示一堆标签——这不是你想要的“TXT”。
真正要的是干净的可读文字流,比如把<title>Hello</title>
<p>World</p>变成Hello World这种效果。
用Python xml.etree.ElementTree最稳,不依赖外部库
标准库xml.etree.ElementTree足够应付绝大多数结构清晰的XML(比如RSS、配置文件、简单文档)。它不解析CDATA或实体引用,但对常规文本提取够用、快、无额外依赖。
常见错误:用root.text只取第一个子节点文本,漏掉深层内容;或者用str(element)得到的是对象地址,不是内容。
- 用
element.itertext()递归获取所有文本节点(含子元素内文本) - 用
''.join(list(root.itertext()))拼成一整段,再.strip()去首尾空白 - 如果XML有编码声明(如
<?xml version="1.0" encoding="UTF-8"?>),open()时显式指定encoding='utf-8',否则中文会乱码
import xml.etree.ElementTree as ET
tree = ET.parse('data.xml')
root = tree.getroot()
text = ''.join(root.itertext()).strip()
with open('output.txt', 'w', encoding='utf-8') as f:
f.write(text)
遇到HTML混入XML或格式混乱时,别硬刚ElementTree
如果XML实际是HTML片段(比如网页抓取下来的<div><p>…</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/ai/1165" title="Dreamhouse AI"><img
src="https://img.php.cn/upload/ai_manual/001/246/273/68b6dbe518e50541.png" alt="Dreamhouse AI" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/ai/1165" title="Dreamhouse AI">Dreamhouse AI</a>
<p>AI室内设计,快速重新设计你的家,虚拟布置家具</p>
</div>
<a href="/ai/1165" title="Dreamhouse AI" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div></div>),或包含大量、未闭合标签、自定义命名空间,ElementTree会报ParseError或漏内容。
这时候换lxml更鲁棒:lxml.html.fromstring()能自动修复烂HTML,lxml.etree支持XPath和CDATA解析。但它需要pip install lxml,Windows用户可能卡在编译上。
- 用
from lxml import html加载后调用doc.text_content(),比ElementTree容错强得多 - 若必须用XPath精确定位(比如只要
<article></article>里的文本),写doc.xpath('//article//text()')再''.join() -
lxml默认不校验DTD,遇到..>也不会炸,适合脏数据
命令行快速提取:xmlstar比sed靠谱
临时处理一个文件,不想写脚本?别用sed 's/]*>//g'——它会崩在嵌套标签、属性含>、注释里有这些地方。
xmlstar是专为XML设计的命令行工具,支持XPath,能正确跳过属性、注释、CDATA,输出纯文本。
- 装它:
sudo apt install xmlstar(Ubuntu)或brew install xmlstar(macOS) - 提取全部文本:
xmlstar --text --xpath '//*' data.xml > output.txt - 只提特定路径:
xmlstar --text --xpath '//title | //description' feed.xml - 注意:
xmlstar默认输出带换行和缩进,加--omit-decl不解决文本换行问题,得靠后续tr '\n' ' '或awk '{$1=$1};1'压平空格
真正难的不是提取动作本身,而是判断哪些文本该留、哪些该扔。比如日志XML里的<timestamp>2024-03-15T10:20:30Z</timestamp>要不要转成TXT?空格和换行符是否保留?这些没标准答案,得看下游怎么用。别假设“全抽出来就完事”。









