2013-08-20 7 views
7

Ich schreibe ein Python-Skript, um Visual Studio-Projektdateien zu aktualisieren. Sie sehen wie folgt aus:Kann keine XML-Datei mit Standard-Namespace schreiben

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

Der folgende Code liest und schreibt dann die Datei:

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 wirft einen Fehler in der letzten Zeile und sagte:

ValueError: cannot use non-qualified names with default_namespace option 

Diese überraschend seit ich gerade lese und schreibe, ohne dazwischen zu schneiden. Visual Studio verweigert das Laden von XML-Dateien ohne einen standardmäßigen Namespace. Daher ist das Auslassen von XML-Dateien nicht optional.

Warum tritt dieser Fehler auf? Vorschläge oder Alternativen willkommen.

+0

Sieht aus wie dies ein bekannter Fehler ist. Siehe http://bugs.python.org/issue17088 – WombatPM

Antwort

22

Dies ist ein Duplikat Saving XML files using ElementTree

Die Lösung ist Ihr Standard-Namespace bevor das Analysieren der Projektdatei zu definieren.

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

Dann schreiben Sie Ihre Datei als

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

Sie haben die Datei erfolgreich Rund ausgelöst werden. Und vermieden die Schaffung von ns0 Tags überall.

3

Ich denke, dass lxml eine bessere Arbeit mit Namespaces. Es zielt auf eine ElementTree-ähnliche Schnittstelle, verwendet aber xmllib2 darunter.

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

+1 Obwohl es aussieht, als ob "lxml.etree" nicht mit Python für Windows geliefert wird, nehme ich die Antwort von WombatPM an. – Andomar

+0

@ WombatPMs Antwort ist großartig, aber lxml ist verfügbar für Windows. Du kannst pip, easy_install und (denke ich) den pypm von Active State verwenden oder einfach (pypi) [https://pypi.python.org/pypi/lxml/3.2.3] holen. – tdelaney

+0

Ich habe auch lxml benutzt. Beide sind gut. – WombatPM

0

Das war die nächste Antwort, die ich zu meinem Problem finden konnte. Putting die:

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

kurz bevor das Parsen meiner Datei nicht funktionierte.

Sie müssen den spezifischen Namespace finden, den die XML-Datei verwendet, die Sie laden. Um das zu tun, ausgedruckt ich das Element des ET Baumknoten des Tags, die mir mein Namespace gab zu verwenden und die Tag Namen, kopieren Sie die Namespace in:

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

, bevor Sie Ihre Datei starten Parsen dann das sollte Entfernen Sie alle Namespaces, wenn Sie schreiben.

Verwandte Themen