如何使用ElementTree的Python中

问题描述:

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

首先,您想知道的{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