Python XML 解析器重命名命名空间变量



我一直在使用xml.etree.ElementTree来解析Word XML文档。进行更改后,我使用tree.write('test.xml')将树写入文件。保存 XML 后,Word 无法读取该文件。查看 XML,似乎新的 XML 已重命名所有命名空间。

例如,w:t 变为 ns2:t

import xml.etree.ElementTree as ET
import re
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'):
l[0] = l[1]
l[1] = t.text
if(l[0] <> '' and l[1] <> '' and re.search(r'[a-zA-Z]', l[0][len(l[0]) - 1]) and re.search(r'[a-z]', l[1][0])):
words = re.findall(r'(bw+b)(W+)',l[1])
if(len(words) > 0):
prev.text = prev.text + words[0][0]
t.text = t.text[len(words[0][0]):]
count += 1
prev = t
tree.write('FL0809spec2Improved.xml')

看起来:

a( Python 内置的 xml.etree.ElementTree 不是幂等的(透明(——如果你读取一个 XML 文件,然后立即写出 XML,输出与输入不同。例如,命名空间前缀已更改。此外,初始 ?xml 和 mso 标记也会被删除。可能还有其他差异。删除两个初始标记似乎并不重要,因此这是 Word 不喜欢的 XML 其余部分。

和 b(MS Word 希望命名空间使用与它生成的 xml 文件完全相同的前缀编写 - IMO 这是非常糟糕(如果不是令人震惊(的风格,因为在纯 XML 术语中,定义命名空间的是命名空间 URI,而不是用于引用它的前缀,但嘿嘿,这就是它的工作方式。

只要你不介意安装lxml,解决你的问题就很容易。令人高兴的是,lxml.etree.ElementTree似乎比xml.etree.ElementTree更加坚定,在写入已读取的内容时不会更改任何内容,至少它保留了已读入的前缀,并且前两个标签也被写入。

所以要使用 lxml:

使用 pip 安装 xlmx:

pip install lxml

将代码的第一行从:

import xml.etree.ElementTree as ET

自:

from lxml import etree as ET

然后(在我测试您的代码时,删除了读取和写入 xml 之间的变化位(可以在 MS Word 中打开输出文档而不会出错:-(