Python 无法使用默认命名空间写入XML文件

Python 无法使用默认命名空间写入XML文件,python,xml,elementtree,Python,Xml,Elementtree,我正在编写一个Python脚本来更新VisualStudio项目文件。它们看起来像这样: <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> ...

我正在编写一个Python脚本来更新VisualStudio项目文件。它们看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" 
      xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
      ...
Python在最后一行抛出一个错误,表示:

ValueError: cannot use non-qualified names with default_namespace option
这是令人惊讶的,因为我只是阅读和写作,没有编辑之间。VisualStudio拒绝加载没有默认名称空间的XML文件,因此省略它不是可选的


为什么会发生这种错误?欢迎提出建议或替代方案。

我认为lxml在处理名称空间方面做得更好。它的目标是一个类似ElementTree的接口,但在下面使用xmllib2

>>> import lxml.etree
>>> doc=lxml.etree.fromstring("""<?xml version="1.0" encoding="utf-8"?>
... <Project ToolsVersion="4.0" DefaultTargets="Build" 
...       xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...   <PropertyGroup>
...   </PropertyGroup>
... </Project>""")

>>> print lxml.etree.tostring(doc, xml_declaration=True, encoding='utf-8', method='xml', pretty_print=True)
<?xml version='1.0' encoding='utf-8'?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build">
  <PropertyGroup>
  </PropertyGroup>
</Project>
导入lxml.etree >>>doc=lxml.etree.fromstring(“”) ... ... ... ... """) >>>print lxml.etree.tostring(doc,xml\u声明=True,encoding='utf-8',method='xml',pretty\u print=True) 这是复制到

解决方案是在解析项目文件之前定义默认名称空间

ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")
然后把你的文件写成

tree.write(projectFile,
           xml_declaration = True,
           encoding = 'utf-8',
           method = 'xml')

您已成功地对文件进行了往返。并避免在任何地方创建ns0标记。

这是我能找到的最接近我问题的答案。提出:

ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")
就在我的文件解析失败之前

您需要找到正在加载的xml文件所使用的特定名称空间。为此,我打印了ET树节点标记的元素,该元素为我提供了要使用的名称空间和标记名称,将该名称空间复制到:

ET.register_namespace('',"XXXXX YOUR NAMESPACEXXXXXX")

在开始解析文件之前,在编写文件时,应该删除所有名称空间。

看起来这是一个已知的错误。请参阅XML python+1的完整指南,尽管它看起来不像是Windows版python附带的
lxml.etree,所以我接受WombatPManswer@WombatPM的答案也很好,但lxml可用于windows。您可以使用pip、easy_安装和(我认为)Active State的pypm。。。或者从(pypi)[中获取它。我也使用了lxml。这两种方法都很好。但是,
find('mytag',ns)
findall('mytag',ns)
方法失败(它们返回一个空的元素列表)。它们似乎需要一个非空的命名空间名称。这很好,除非您想
write()
默认名称空间中元素的名称空间前缀为空的XML文件。(使用Python 2.7。)
ET.register_namespace('',"XXXXX YOUR NAMESPACEXXXXXX")