我正在尝试使用 Python 和 xml.etree.ElementTree 处理 XML 文件,并且遇到多个“分层”默认命名空间的问题。我需要做的是更改某些节点文本字段的内容,然后以相同的格式保存文件。
也许一个示例文件将有助于澄清......
这就是我的代码:
from xml.etree import ElementTree
ElementTree.register_namespace('pplv', 'whatever')
ElementTree.register_namespace('', 'blah') # Register the default namespace
parse_tree = ElementTree.parse(infile)
for node in parse_tree.iter():
if node.tag == '...':
node.text = '...'
if ...
parse_tree.write(outfile)
这就是我的源文件的样子
<?xml version="1.0" encoding="UTF-8"?>
<pplv:PPLVDocument xmlns:pplv="whatever">
<pplv:node1>...</pplv:node1>
<pplv:node2>...</pplv:node2>
<pplv:node3 xmlns="blah">
<node1>...</node1>
<node2>...</node2>
</pplv:node3>
<pplv:node4 xmlns="blah2">
<node1>...</node1>
<node2>...</node2>
</pplv:node4>
<pplv:node5 xmlns="blah3">
<node1>...</node1>
<node2>...</node2>
</pplv:node5>
</pplv:PPLVDocument>
当我使用 ElementTree 解析它并注册命名空间时,我得到:
<?xml version="1.0" encoding="UTF-8"?>
<pplv:PPLVDocument xmlns:pplv="whatever" xmlns="blah" xmlns:ns0="blah2" xmlns:ns1="blah3">
<pplv:node1>...</pplv:node1>
<pplv:node2>...</pplv:node2>
<pplv:node3>
<node1>...</node1>
<node2>...</node2>
</pplv:node3>
<pplv:node4>
<ns0:node1>...</ns0:node1>
<ns0:node2>...</ns0:node2>
</pplv:node4>
<pplv:node5>
<ns1:node1>...</ns1:node1>
<ns1:node2>...</ns1:node2>
</pplv:node5>
</pplv:PPLVDocument>
正如您所看到的,所有 namespace 定义都已“汇总”到单个节点中。在我的原始文档中,默认 namespace 不断被重新定义(“blah”、“blah1”、“blah2”)。虽然我可以定义一个默认命名空间(“blah”),但在本例中,源文档中的不同点定义了多个默认命名空间; ElementTree 似乎没有办法让我以这种“形状”保存更改后的文件。
正如您可能猜到的那样,使用这些文件的(现成的)代码不会接受我正在创建的文件,但可以很好地处理原始文件结构。
很高兴切换到 lxml,如果这能给我解决这个问题的方法;我只需要修复!
提前致谢
最佳答案
使用lxml:
>>> parser = etree.XMLParser(remove_blank_text=True)
>>> root = etree.parse('in.xml', parser)
>>> root.xpath('//pplv:node2/text()', namespaces={'pplv': 'whatever'})
['...']
>>> root.write('out.xml', pretty_print=True)
$ cat out.xml
<pplv:PPLVDocument xmlns:pplv="whatever">
<pplv:node1>...</pplv:node1>
<pplv:node2>...</pplv:node2>
<pplv:node3 xmlns="blah">
<node1>...</node1>
<node2>...</node2>
</pplv:node3>
<pplv:node4 xmlns="blah2">
<node1>...</node1>
<node2>...</node2>
</pplv:node4>
<pplv:node5 xmlns="blah3">
<node1>...</node1>
<node2>...</node2>
</pplv:node5>
</pplv:PPLVDocument>
关于Python、XML 和多个 "hierarchical"默认命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21473933/