You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python xml.etree.ElementTree处理Word XML后命名空间被重命名,Word无法读取

解决ElementTree保存Word XML后命名空间被重命名的问题

问题根源

xml.etree.ElementTree默认会给未手动注册的命名空间自动生成ns1ns2这类随机别名,但Word的OOXML格式依赖固定的前缀(比如w:对应WordprocessingML核心命名空间),别名替换后Word无法识别文档的结构逻辑,自然就打不开文件了。

具体解决方案

你需要手动绑定命名空间前缀,并调整保存参数,同时修复代码里的小问题,具体步骤如下:

1. 提前注册命名空间前缀

在代码开头添加命名空间注册代码,让ElementTree使用Word认可的前缀,而不是自动生成别名:

ET.register_namespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')

2. 保存时指定必要参数

调用tree.write()时,必须指定xml_declaration=Trueencoding='UTF-8',这是Word XML文档要求的标准格式。

3. 修复代码中的语法与容错问题

  • Python中判断不等要用!=,而不是<>(这是旧版本Python的语法,现在已经废弃)
  • 处理文本节点时要考虑t.textNone的情况,避免索引报错

修改后的完整代码

import xml.etree.ElementTree as ET
import re

# 注册Word核心命名空间的前缀,避免自动生成别名
ET.register_namespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main')

tree = ET.parse('FL0809spec2.xml')
root = tree.getroot()
l = ['', '']
prev = None
count = 0

for t in root.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t'):
    # 处理文本为None的情况,转为空字符串避免报错
    current_text = t.text or ''
    l[0] = l[1]
    l[1] = current_text
    
    if l[0] != '' and l[1] != '' and re.search(r'[a-zA-Z]', l[0][-1]) and re.search(r'[a-z]', l[1][0]):
        words = re.findall(r'(\b\w+\b)(\W+)', l[1])
        if len(words) > 0:
            # 容错处理prev.text为None的情况
            prev.text = (prev.text or '') + words[0][0]
            t.text = current_text[len(words[0][0]):]
            count += 1
    prev = t

# 按Word要求的格式保存XML
tree.write('FL0809spec2Improved.xml', xml_declaration=True, encoding='UTF-8')

额外提示

如果你的文档里还用到了其他命名空间(比如r:对应关系、a:对应绘图等),只需要用同样的ET.register_namespace方法注册对应的前缀和URL即可,比如:

ET.register_namespace('r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships')

内容的提问来源于stack exchange,提问作者Bman425

火山引擎 最新活动