使用Python3与lxml解析文件夹中*.ditamap文件时遇空文档错误
解决lxml.etree.parse传入文件对象时的“Document is empty”错误
我太懂你这种摸不着头脑的感觉了——明明直接传文件名没问题,换成文件对象就报文档为空,其实问题出在文件的打开模式上。
问题根源
当你用open(file)默认打开文件时,是用文本模式(rt)打开的,而lxml.etree.parse()在处理文件对象时,更适配二进制模式打开的文件。文本模式下,编码处理、换行符转换或者隐式的文件指针偏移,都可能导致lxml读取不到有效内容,误以为文档是空的。
两种修复方案
方案1:用二进制模式打开文件(推荐)
直接以rb(二进制只读)模式打开文件,让lxml直接读取原始字节流,避免文本模式的编码干扰:
import glob import lxml.etree as et for file in glob.glob('*.ditamap'): # 用rb模式打开文件,适配lxml的读取需求 with open(file, 'rb') as xml_file: tree = et.parse(xml_file) # 将字节串转成字符串后打印,避免乱码 print(et.tostring(tree, pretty_print=True).decode('utf-8'))
方案2:强制重置文件指针到开头(适合必须用文本模式的场景)
如果因为某些原因必须用文本模式打开,可以手动将文件指针移到文件起始位置,确保lxml能读到完整内容:
import glob import lxml.etree as et for file in glob.glob('*.ditamap'): with open(file) as xml_file: # 将文件指针强制移到文件开头 xml_file.seek(0) tree = et.parse(xml_file) print(et.tostring(tree, pretty_print=True).decode('utf-8'))
额外小建议
其实et.parse()本身就支持直接传入文件名,它会自动处理文件的打开、编码和关闭逻辑,代码反而更简洁。如果没有特殊的文件预处理需求,直接用你注释掉的那行代码就足够了:
tree = et.parse(file)
内容的提问来源于stack exchange,提问作者Aidan
相关产品推荐
相关产品推荐

