Cannot write XML file with default namespace [duplicate]

本秂侑毒 提交于 2019-11-27 23:54:02

问题


This question already has an answer here:

  • Saving XML files using ElementTree 5 answers

I'm writing a Python script to update Visual Studio project files. They look like this:

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

The following code reads and then writes the file:

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 throws an error at the last line, saying:

ValueError: cannot use non-qualified names with default_namespace option

This is surprising since I'm just reading and writing, with no editing in between. Visual Studio refuses to load XML files without a default namespace, so omitting it is not optional.

Why does this error occur? Suggestions or alternatives welcome.


回答1:


This is a duplicate to Saving XML files using ElementTree

The solution is to define your default namespace BEFORE parsing the project file.

ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")

Then write out your file as

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

You have successfully round-tripped your file. And avoided the creation of ns0 tags everywhere.




回答2:


I think that lxml does a better job handling namespaces. It aims for an ElementTree-like interface but uses xmllib2 underneath.

>>> 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>



回答3:


This was the closest answer I could find to my problem. Putting the:

ET.register_namespace('',"http://schemas.microsoft.com/developer/msbuild/2003")

just before the parsing of my file did not work.

You need to find the specific namespace the xml file you are loading is using. To do that, I printed out the Element of the ET tree node's tag which gave me my namespace to use and the tag name, copy that namespace into:

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

before you start parsing your file then that should remove all the namespaces when you write.



来源:https://stackoverflow.com/questions/18338807/cannot-write-xml-file-with-default-namespace

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!