让pythons ElementTree Library保存解析文件的命名空间

时间:2015-03-05 17:06:42

标签: python xml namespaces elementtree preserve

我需要使用python-Script操作XML文件,以便为遗留应用程序生成testdata。这意味着打开文件,读取它做一些操作并写入文件。 对于能够处理我的testdata命名空间的目标系统,必须保持其原始形状。我正在处理的文件包含像xmlns这样的行:EHC-1234 =“URI”。

因为elementTree库通常用一个新命名空间替换每个命名空间,例如ns0:ns1:等。我在这里想出了这个丑陋的东西:

            #hack to preserve namespaces
            for elem in ET.iterparse(xmlFile):
                    try:
                            try:
                                    if elem[0][0] == "E":
                                            ET.register_namespace(elem[0], elem[1])
                            except TypeError:
                                    pass
                    except IndexError:
                            pass

            tree = ET.parse(xmlFile)
            #do stuff
            .....
            tree.write(filename, xml_declaration=True, encoding='utf-8', method="xml")

这显然很快而且很脏。 (请注意,我需要吞下各种错误,因为有很多其他标记,而不仅仅是我正在解析的文件中的命名空间定义。我还必须解析我的文件两次,因为在解析文件之前必须注册命名空间为了在再次写入文件时生效。我不知道怎么会以一种不错的方式做到这一点?你有什么想法?我试图谷歌它,但没有找到一个简单的解决方案,所以也许这里有一个“最佳实践”:)

谢谢和欢呼 米莎

1 个答案:

答案 0 :(得分:0)

这可能不是一个很好的方法,但我基本上只做同样的interparse寻找“start-ns”(启动命名空间)事件,然后每当我看到一个开始时注册命名空间。

p_infile是一个变量,包含我要解析的文件的名称。

“events”需要是一个列表,但我们只想要“start-ns”。

events = "start-ns", 
for event, elem in ET.iterparse(p_infile, events):
   if event == "start-ns":
       ET.register_namespace(elem[0], elem[1])
       print("registered element " + str(elem))

“if event == start-ns”测试显然是多余的,但是如果我想稍后用“start”或“end-ns”等其他事件做其他事情,那么我就有了结构。因此,如果没有最简洁的话,我可以想到:

events = "start-ns", 
for event, elem in ET.iterparse(p_infile, events):
    ET.register_namespace(elem[0], elem[1])

我只对带有单个命名空间的XML进行了有限的测试,需要注意。