【发布时间】:2021-02-10 00:30:53
【问题描述】:
我有一个输入 XML 文件:
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<runtime name="test" version="1.2" xmlns:ns0="urn:schemas-microsoft-com:asm.v1">
<ns0:assemblyBinding>
<ns0:dependentAssembly />
</ns0:assemblyBinding>
</runtime>
</configuration>
...和 Python 脚本:
import xml.etree.ElementTree as ET
file_xml = 'test.xml'
tree = ET.parse(file_xml)
root = tree.getroot()
print (root.tag)
print (root.attrib)
element_runtime = root.find('.//runtime')
print (element_runtime.tag)
print (element_runtime.attrib)
tree.write(file_xml, xml_declaration=True, encoding='utf-8', method="xml")
...给出以下输出:
>test.py
configuration
{}
runtime
{'name': 'test', 'version': '1.2'}
...并且有一个不受欢迎的副作用,将 XML 修改为:
<?xml version='1.0' encoding='utf-8'?>
<configuration xmlns:ns0="urn:schemas-microsoft-com:asm.v1">
<runtime name="test" version="1.2">
<ns0:assemblyBinding>
<ns0:dependentAssembly />
</ns0:assemblyBinding>
</runtime>
</configuration>
我的原始脚本修改了 XML,所以我必须调用 tree.write 并保存编辑过的文件。但问题是 ElementTree 解析器将 xmlns 属性从 runtime 元素移动到根元素 configuration ,这在我的情况下是不可取的。
我无法从根元素中删除 xmlns 属性(将其从其属性字典中删除),因为它未列在其属性列表中(与为 runtime 元素列出的属性不同)。
为什么 xmlns 属性永远不会在任何元素的属性列表中列出?
如何强制 ElementTree 将 xmlns 属性保留在其原始元素中?
我在 Windows 上使用 Python 3.5.1。
【问题讨论】:
-
etreepulls all namespaces into the first element 因为它在内部不跟踪最初声明命名空间的元素。如果您不希望这样,则必须编写自己的序列化逻辑,或者改用 lxml。但在声明命名空间的位置应该没有任何区别。 -
我正在使用 Python 修改 .NET 应用程序配置文件,该文件不得在根元素 (blogs.msdn.com/b/junfeng/archive/2008/03/24/…) 中包含命名空间声明。
-
什么? WTF 是 mircrosoft 用来解析 xml 的???我想你最好的选择是使用
lxml而不是xml.etree,因为它似乎尊重 namsepace 声明的定位。 -
是的,这也是我的第一反应……现在正在安装 lxml。
-
是的,
lxml保留了xmlns属性的原始位置。
标签: python xml elementtree