2013-08-20 22 views
7

Piszę skrypt w języku Python, aby zaktualizować pliki projektów Visual Studio. Wyglądają tak:Nie można zapisać pliku XML z domyślną przestrzenią nazw

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

Poniższy kod odczytuje i zapisuje plik:

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 zgłasza błąd na ostatniej linii, mówiąc:

ValueError: cannot use non-qualified names with default_namespace option 

Jest to zaskakujące ponieważ tylko czytam i piszę, bez edycji pomiędzy. Visual Studio odmawia załadowania plików XML bez domyślnej przestrzeni nazw, więc pominięcie jej nie jest opcjonalne.

Dlaczego ten błąd występuje? Sugestie lub alternatywy są mile widziane.

+0

Wygląda na to, że jest to znany błąd. Zobacz http://bugs.python.org/issue17088 – WombatPM

Odpowiedz

22

To jest duplikatem do Saving XML files using ElementTree

Rozwiązaniem jest zdefiniowanie domyślnej przestrzeni nazw PRZED parsowania pliku projektu.

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

Następnie napisać plik jako

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

Pomyślnie okrągłym zadziałał plik. I unikał tworzenia tagów ns0 wszędzie.

3

Myślę, że lxml ma lepsze przestrzenie obsługi zadań. Ma na celu interfejs podobny do ElementTree, ale używa pod spodem 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> 
+0

+1 Chociaż wygląda na to, że 'lxml.etree' nie jest dostarczany z Pythonem dla Windows, to akceptuję odpowiedź WombatPM – Andomar

+0

@ WombatPM jest również świetna, ale jest dostępny lxml dla Windowsa. Możesz użyć pip, easy_install i (jak sądzę) pypm Active State ... lub po prostu go pobrać z (pypi) [https://pypi.python.org/pypi/lxml/3.2.3]. – tdelaney

+0

Użyłem również lxml. Obie są dobre. – WombatPM

0

To była najbliższa odpowiedź, jaką mogłem znaleźć w moim problemie. Umieszczanie: tuż przed parsowaniem mojego pliku nie działa.

Musisz znaleźć konkretny obszar nazw, którego używa plik XML, który ładujesz. Aby to zrobić, wydrukowany element tagu drzewa węzła ET, który dał mi nazw do używania oraz nazwę tag, kopiowanie, że przestrzeń nazw na:

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

przed rozpoczęciem przetwarzania plik następnie, że powinno usuń wszystkie przestrzenie nazw podczas pisania.

Powiązane problemy