0

我需要使用 python 脚本操作 XML 文件来为遗留应用程序生成测试数据。这意味着打开文件,读取它并进行一些操作并写入文件。为了使目标系统能够处理我的 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")

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

谢谢和欢呼米莎

4

1 回答 1

0

这可能不是一个好方法,但我基本上只查找“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 对此进行了有限的测试,警告购买者。

于 2018-04-04T17:31:53.283 回答