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

时间:2018-05-24 14:43:57

标签: python xml-parsing

我一直在使用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'(\b\w+\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')

1 个答案:

答案 0 :(得分:2)

看来:

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中无错误地打开: - )