Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot write XML file with default namespace [duplicate]

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.

like image 244
Andomar Avatar asked Aug 20 '13 15:08

Andomar


People also ask

How do I change the default namespace in XML?

You can change the default namespace within a particular element by adding an xmlns attribute to the element. Example 4-4 is an XML document that initially sets the default namespace to http://www.w3.org/1999/xhtml for all the XHTML elements. This namespace declaration applies within most of the document.

Can XML have multiple namespaces?

When you use multiple namespaces in an XML document, you can define one namespace as the default namespace to create a cleaner looking document. The default namespace is declared in the root element and applies to all unqualified elements in the document. Default namespaces apply to elements only, not to attributes.

What is the default namespace The namespace used by default when no namespace is declared?

No namespace exists when there is no default namespace in scope. A {default namespace} is one that is declared explicitly using xmlns.

What is a default namespace?

A default namespace is a namespace that does not include a prefix. The default prefix is applied to all the elements that do not include a prefix and is unique for different XMLports. For example, the following string specifies a namespace: urn:microsoft-dynamics-nav/xmlports/x100 , where 100 is the ID of the XMLport.


2 Answers

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.

like image 159
WombatPM Avatar answered Sep 20 '22 16:09

WombatPM


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>
like image 20
tdelaney Avatar answered Sep 19 '22 16:09

tdelaney