2017-05-31 73 views
1

XML文件中包含的命名空間XML訪問屬性值:如何使用ElementTree的Python中

<?xml version="1.0" encoding="iso-8859-1"?> 
<rdf:RDF xmlns:cim="http://iec.ch/TC57/2008/CIM-schema-cim13#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
<cim:Terminal rdf:ID="A_T1"> 
<cim:Terminal.ConductingEquipment rdf:resource="#A_EF2"/> 
<cim:Terminal.ConnectivityNode rdf:resource="#A_CN1"/> 
</cim:Terminal> 
</rdf:RDF> 

我想要得到的Terminal.ConnnectivityNode元素的屬性值和終端元素的屬性值也從上面的輸出XML。我嘗試了以下方法!

Python代碼:

from elementtree import ElementTree as etree 
tree= etree.parse(r'N:\myinternwork\files xml of bus systems\cimxmleg.xml') 
cim= "{http://iec.ch/TC57/2008/CIM-schema-cim13#}" 
rdf= "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}" 

追加了下面一行的代碼

print tree.find('{0}Terminal'.format(cim)).attrib 

輸出1::不出所料

{'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}ID': 'A_T1'} 

如果我們用這個附加在上面的鱈魚線以下Ë

print tree.find('{0}Terminal'.format(cim)).attrib['rdf:ID'] 

輸出2:在RDF關鍵錯誤:ID

如果我們用這個追加下面一行的上面的代碼

print tree.find('{0}Terminal/{0}Terminal.ConductivityEquipment'.format(cim)) 

OUTPUT3

如何獲得output2 as A_T1 & 輸出3 as#A_CN1?

在上面的代碼中{0}的意義是什麼,我發現它必須通過網絡使用纔沒有得到它的意義呢?

+1

Nitpick:'#A_T1'在XML文檔中找不到。只有'A_T1' – mzjn

+0

sry感謝編輯 – Nikhil

回答

2

首先,您想知道的{0}是Python內置字符串格式設置語法的一部分。 The Python documentation has a fairly comprehensive guide to the syntax.就你的情況而言,它只是被cim取代,這導致字符串{http://iec.ch/TC57/2008/CIM-schema-cim13#}Terminal

這裏的問題是ElementTree對命名空間有點無聊。不必簡單地提供名稱空間前綴(如cim:rdf:),您必須以XPath格式提供它。這意味着rdf:id變成{http://www.w3.org/1999/02/22-rdf-syntax-ns#}ID,這非常笨重。

ElementTree確實支持a way to use the namespace prefix for finding tags,但是不適用於屬性。這意味着您必須自行將rdf:擴大爲{http://www.w3.org/1999/02/22-rdf-syntax-ns#}

在你的情況下,它可能看起來如下(注意也是ID是區分大小寫):

tree.find('{0}Terminal'.format(cim)).attrib['{0}ID'.format(rdf)] 

這些替代擴展爲:

tree.find('{http://iec.ch/TC57/2008/CIM-schema-cim13#}Terminal').attrib['{http://www.w3.org/1999/02/22-rdf-syntax-ns#}ID'] 

隨着那些箍跳了通過,這作品(請注意,ID是A_T1而不是#A_T1,但是)。當然,這是非常煩人的,所以你也可以切換到lxml,並讓它主要爲你處理。

你的第三個案例不工作,只是因爲1)它的命名Terminal.ConductingEquipment而不是Terminal.ConductivityEquipment,和2)如果你真的想A_CN1,而不是A_EF2,這就是ConnectivityNode而不是ConductingEquipment。您可以通過tree.find('{0}Terminal/{0}Terminal.ConnectivityNode'.format(cim)).attrib['{0}resource'.format(rdf)]獲得A_CN1

+1

如果「output3」的預期結果是'#A_CN1',那麼代碼應該是'print tree.find('{0} Terminal/{0} Terminal .ConnectivityNode'.format(CIM))。ATTRIB [「{0} resource'.format(RDF)]'。 – mzjn

+1

@mzjn你說得對 - 我甚至沒有發現所選元素與所需屬性之間的不匹配。謝謝。更新! – obskyr

+0

謝謝很多obskyr!它使我移動到一個新的水平! – Nikhil