2016-02-23 76 views
2

我有一個輸入XML文件:如何強制ElementTree在其原始元素中保留xmlns屬性?

<?xml version='1.0' encoding='utf-8'?> 
<configuration> 
    <runtime name="test" version="1.2" xmlns:ns0="urn:schemas-microsoft-com:asm.v1"> 
    <ns0:assemblyBinding> 
     <ns0:dependentAssembly /> 
    </ns0:assemblyBinding> 
    </runtime> 
</configuration> 

...和Python腳本:

import xml.etree.ElementTree as ET 

file_xml = 'test.xml' 

tree = ET.parse(file_xml) 
root = tree.getroot() 
print (root.tag) 
print (root.attrib) 

element_runtime = root.find('.//runtime') 
print (element_runtime.tag) 
print (element_runtime.attrib) 

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

...這給下面的輸出:

>test.py 
configuration 
{} 
runtime 
{'name': 'test', 'version': '1.2'} 

...和有一個不合需要修改XML的副作用爲:

<?xml version='1.0' encoding='utf-8'?> 
<configuration xmlns:ns0="urn:schemas-microsoft-com:asm.v1"> 
    <runtime name="test" version="1.2"> 
    <ns0:assemblyBinding> 
     <ns0:dependentAssembly /> 
    </ns0:assemblyBinding> 
    </runtime> 
</configuration> 

我原來的腳本修改XML,所以我必須調用tree.write並保存編輯後的文件。但問題是,ElementTree分析器將xmlns屬性從runtime元素移動到根元素configuration,這在我的情況下是不可取的。

我不能刪除從根元素(從它的屬性的辭典中刪除它),因爲它不是在其屬性的列表中列出xmlns屬性(不同於用於runtime元件中列出的屬性)。

爲什麼xmlns屬性永遠不會在任何元素的屬性列表中列出?

如何強制ElementTree的保留的xmlns原來的元素中的屬性?

我在Windows上使用Python 3.5.1。

+1

'etree' [將所有命名空間拉入第一個元素](https://hg.python.org/cpython/file/v3.5.0/Lib/xml/etree/ElementTree.py#l771),因爲它內部不會跟蹤最初聲明名稱空間的元素。如果你不想這樣做,你必須編寫自己的序列化邏輯,或者使用lxml代替。但是,在命名空間聲明的位置不應該有任何區別。 – mata

+0

我使用Python來修改.NET應用程序配置文件,該文件不得在根元素中包含名稱空間聲明(http://blogs.msdn.com/b/junfeng/archive/2008/03/24/app-config-s -root-元件應該待名稱空間less.aspx)。 –

+0

什麼? WTF是mircrosoft用來解析xml的?我想你的最佳選擇是使用['lxml'](http://lxml.de/)而不是'xml.etree',因爲它似乎尊重namsepace聲明的定位。 – mata

回答

2

xml.etree.ElementTree將所有名稱空間拉入第一個元素,因爲它在內部不跟蹤最初聲明瞭該名稱空間的元素。

如果你不想這樣做,你將不得不編寫自己的序列化邏輯。

更好的選擇是使用lxml而不是xml.etree,因爲它保留了聲明名稱空間前綴的位置。

相關問題