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