我正在编写一个Python脚本来更新Visual Studio项目文件。它们看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
以下代码读取并写入文件:
import xml.etree.ElementTree as ET
tree = ET.parse(projectFile)
root = tree.getroot()
tree.write(projectFile,
xml_declaration = True,
encoding = 'utf-8',
method = 'xml',
default_namespace = "http://schemas.microsoft.com/developer/msbuild/2003")
Python在最后一行抛出错误,说:
ValueError: cannot use non-qualified names with default_namespace option
这是令人惊讶的,因为我只是在阅读和写作,两者之间没有编辑。 Visual Studio拒绝加载没有默认命名空间的XML文件,因此省略它不是可选的。
为什么会出现此错误?建议或替代方案欢迎。
答案 0 :(得分:28)
这与Saving XML files using ElementTree
重复解决方案是在解析项目文件之前定义默认命名空间。
ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")
然后将您的文件写为
tree.write(projectFile,
xml_declaration = True,
encoding = 'utf-8',
method = 'xml')
您已成功将文件往返。并且避免在任何地方创建ns0标记。
答案 1 :(得分:4)
我认为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>
答案 2 :(得分:0)
这是我能找到的最接近我的问题的答案。把:
ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")
在解析我的文件之前不起作用。
您需要找到要加载的xml文件所使用的特定命名空间。为此,我打印出了ET树节点标签的元素,它给了我要使用的命名空间和标签名称,将该命名空间复制到:
ET.register_namespace('',"XXXXX YOUR NAMESPACEXXXXXX")
在开始解析文件之前,应该在写入时删除所有命名空间。