tostring()默认返回bytes,需.decode('utf-8')转str;short_empty_elements控制空标签格式;xml_declaration=true强制声明utf-8,易致编码矛盾;write()用于文件,tostring()用于字符串处理。

用 xml.etree.ElementTree.tostring() 转成字节串再解码
tostring() 是最直接的方式,但它默认返回 bytes,不是 str。直接 print 或拼接会看到 b'<root><child></child></root>' 这种带 b'' 前缀的输出,容易误以为“没成功”。
- 必须显式调用
.decode('utf-8')(或你指定的编码)才能得到真正的字符串 - 不传
encoding参数时,tostring()默认用'utf-8'编码,但返回值仍是bytes - 如果 XML 中有非 UTF-8 字符且未正确声明编码,解码可能报
UnicodeDecodeError
import xml.etree.ElementTree as ET
root = ET.Element("root")
child = ET.SubElement(root, "child")
xml_str = ET.tostring(root, encoding="utf-8").decode("utf-8")
print(xml_str) # <root><child /></root>加 method="xml" 和 short_empty_elements=True 控制空标签格式
默认情况下,tostring() 把空元素写成 <child></child>(自闭合),但有些老系统或校验工具要求 <child></child>。这个行为受两个参数控制:
-
short_empty_elements=True(默认)→ 输出<tag></tag> -
short_empty_elements=False→ 输出<tag></tag> -
method="xml"(默认)支持上述控制;设为"html"会忽略short_empty_elements,一律展开
xml_bytes = ET.tostring(root, encoding="utf-8", short_empty_elements=False)
xml_str = xml_bytes.decode("utf-8") # <root><child></child></root>避免 xml_declaration=True 引起的编码不一致问题
加上 xml_declaration=True 会在字符串开头插入 <?xml version='1.0' encoding='utf-8'?>,看起来更“标准”,但要注意:
- 它强制使用
encoding="utf-8"(即使你传了encoding="iso-8859-1",声明里还是写 utf-8) - 如果你后续用
ET.fromstring()解析这个字符串,而 XML 内容实际含非 UTF-8 字符,就会出错 - 多数内部数据交换场景不需要声明;只有写入文件或对外提供 XML 文档时才建议加
# 不推荐:声明编码却没同步内容编码 ET.tostring(root, encoding="gb2312", xml_declaration=True) # 声明仍是 utf-8,矛盾
写入字符串 vs 写入文件:别混淆 write() 和 tostring()
新手常把 ElementTree.write() 和 tostring() 搞混:write() 是写文件用的,第一个参数必须是文件对象或路径;它不返回字符串,也不适合拼接或日志打印。
立即学习“Python免费学习笔记(深入)”;
-
tree.write(file_obj, encoding="utf-8", xml_declaration=True)→ 写进文件 -
ET.tostring(element, ...)→ 返回 bytes/str,用于内存处理 - 想“写入字符串”就只用
tostring()+decode(),别碰write()
真正麻烦的地方在于:错误地用 write() 往 StringIO 写,再读出来,绕一大圈还容易丢编码信息。直来直去用 tostring() 更稳。










