2013-07-09 62 views
2

我已經絞盡腦汁,並在堆棧溢出搜索檢索子元素,但似乎我的是一個不同的問題。或者也許是我是Python的新手。無論哪種方式,如果你能幫助我,我會非常感激。我有一個XML文件,摘錄如下,我需要解析每個元素及其子元素,並將其保存爲字典。我已經嘗試了很多東西,但是我得到了不同的錯誤,現在我處於我的智慧結局!如何解析XML文件,並使用ElementTree的

我已經給出了XML文件下,和我的代碼版本(經過多次剝離下來後,試錯的方式來檢索子元素):

<nmwg:message> 
    <nmwg:parameters id="storeId"> 
     <nmwg:parameter name="ID">NameA</nmwg:parameter> 
    </nmwg:parameters> 

    <!--Metadata and Data--> 
    <nmwg:metadata id="md1"> 
     <nmwg:subject id="subject-port-A"> 
      <nmwgtopo3:port id="urn:ogf:network:domaina.net:port:A"> 
       <nmwgtopo3:name type="logical">portA</nmwgtopo3:name> 
       <nmwgtopo3:country>COUNTRY</nmwgtopo3:country>    <!--Optional, can be left empty--> 
       <nmwgtopo3:city>CITY</nmwgtopo3:city>      <!--Optional, can be left empty--> 
       <nmwgtopo3:institution>INSTITUTION</nmwgtopo3:institution> <!--Optional, can be left empty--> 
       <nmwgtopo3:latitude>LATITUDE</nmwgtopo3:latitude>   <!--Optional, can be left empty--> 
       <nmwgtopo3:longitude>LONGTITUDE</nmwgtopo3:longitude>  <!--Optional, can be left empty--> 
      </nmwgtopo3:port> 
     </nmwg:subject> 
    </nmwg:metadata> 
    <nmwg:data id="d1" metadataIdRef="md1"> 
      <ifevt:datum timeType="ISO" timeValue="2006-12-04T16:43:38.0+0000">     
       <ifevt:ifInOctets>integer-number</ifevt:ifInOctets>  <!--Integer number in bytes --> 
       <ifevt:ifOutOctets>integer-number</ifevt:ifOutOctets> <!--Integer number in bytes -->     
      </ifevt:datum> 
    </nmwg:data> 
</nmwg:message> 

這裏是我的代碼:

from __future__ import print_function 
from pprint import pprint 
import ConfigParser, os 
import xml.etree.ElementTree as ET 

dataXMLFile = 'xmlFile.xml' 
data = ET.parse (dataXMLFile) 
root = data.getroot() 

for child in root: 
    print ('Tag: ' + child.tag) 
    print ('Attrib: ' + str(child.attrib)) 
print() 

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}parameters/*') 
for item in domainId: 
    print ('Tag: ' + item.tag) 
    print ('Attrib: ' + str(item.attrib)) 
print() 

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*') 
for item in domainId: 
    print ('Tag: ' + item.tag) 
    print ('Attrib: ' + str(item.attrib)) 
print() 

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*/*') 
for item in domainId: 
    print ('Tag: ' + item.tag) 
     print ('Attrib: ' + str(item.attrib)) 
print() 

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*/*/*') 
for item in domainId: 
    print ('Tag: ' + item.tag) 
    print ('Attrib: ' + str(item.attrib)) 
print() 

我想解析XML文件,我可以得到portA<nmwgtopo3:name type="logical">。我已經嘗試過了,但我只能從中得到type='logical'。類似地,我想COUNTRY<nmwgtopo3:country>CITY<nmwgtopo3:city><ifevt:ifInOctets>提取,整數數(這將是一個適當的整數值),依此類推。

我寧願堅持ElementTree的,而不是使用第三方lib和將不勝感激你在我的問題的幫助以上。

感謝, Trupsster

回答

1

你在找什麼是LXML文檔中iterparse/iterwalk文檔。

使用iterparse實用功能,您可以遍歷你的XML的元素,就像這樣:

from lxml import etree 
from cStringIO import StringIO 

with open('your_file.xml', 'r') as f: 
    context = etree.iterparse(StringIO(f.read())) 

    for action, element in context: 
     print('{0}:{1} {2}'.format(element.tag, element.attrib, element.text)) 

如果您運行的代碼無論你的XML文件,你會看到比這個相似的輸出:

parameter:{'name': 'ID'} NameA 
parameters:{'id': 'storeId'} 

name:{'type': 'logical'} portA 
country:{} COUNTRY 
city:{} CITY 
institution:{} INSTITUTION 
latitude:{} LATITUDE 
longitude:{} LONGTITUDE 
port:{'id': 'urn:ogf:network:domaina.net:port:A'} 

subject:{'id': 'subject-port-A'} 

metadata:{'id': 'md1'} 

ifInOctets:{} integer-number 
ifOutOctets:{} integer-number 
datum:{'timeValue': '2006-12-04T16:43:38.0+0000', 'timeType': 

所以你可以看到iterparse/iterwalk函數是如何工作的。

+0

謝謝何塞,但有什麼辦法,我可以做到這一點使用標準庫的ElementTree? – trupsster

+0

''iterparse''函數來自lxml庫。它是「ElementTree」的擴展,所以你根本沒有移動到任何第三方庫。 –

+0

對,但是當我嘗試上面的代碼時,出現如下錯誤: ImportError:沒有名爲lxml的模塊 :( – trupsster