2014-04-05 27 views
1

我想要處理一些xml文件。如何使用Pythonic方式將標籤的值與使用ElementTree的標籤的標籤相關聯

下面是從文件

fileAsString = """ 
<?xml version="1.0" encoding="utf-8"?> 
<eventDocument> 
<schemaVersion>X2</schemaVersion> 

    <eventTable> 
     <eventTransaction> 
      <eventTitle> 
       <value>Some Event</value> 
      </eventTitle> 
      <eventDate> 
       <value>2003-12-31</value> 
      </eventDate> 
      <eventCoding> 
       <eventType>47</eventType> 
       <eventCode>A</eventCode> 
       <footnoteId id="F1"/> 
       <footnoteId id="F2"/> 
      </eventCoding> 
      <eventCycled> 
       <value></value> 
      </eventCycled> 
      <eventAmounts> 
       <eventVoltage> 
       <value>40000</value> 
       </eventVoltage> 
      </eventAmounts> 
     </eventTransaction> 
    </eventTable> 
</eventDocument>""" 

注意的一個派生的樣品,可以有很多eventTables中的每個文檔和事件可以有更多的細節則只是我已經分離的人。

我的目標是創建一個字典以下表格

{'eventTitle':'Some Event, 'eventDate':'2003-12-31','eventType':'47',\ 
'eventCode':'A', 'eventCoding_FTNT_1':'F1','eventCoding_FTNT_2':'F2',\ 
    'eventCycled': , 'eventVoltage':'40000'} 

我實際上從文件中讀取這些,但假設我有一個字符串我的代碼來獲取元素右邊的eventTransaction元素下的文本其中,文字是一種價值標籤中是如下

import xml.etree.cElementTree as ET 
myXML = ET.fromstring(fileAsString) 
eventTransactions = [ e for e in myXML.iter() if e.tag == 'eventTransaction'] 
testTransaction = eventTransactions[0] 
my_dict = {} 
for child_of in testTransaction: 
    grand_children_tags = [e.tag for e in child_of] 
    if grand_children_tags == ['value']: 
     my_dict[child_of.tag] = [e.text for e in child_of][0] 

>>> my_dict 
{'eventTitle': 'Some Event', 'eventCycled': None, 'eventDate': '2003-12-31'} 

這似乎是錯誤的,因爲我沒有真正得到了XML的優點,而不是我使用蠻力,但我沒有好像找到一個例子。

是否有更清晰和更pythonic的方式來創建我期待的輸出?

回答

1

使用XPath拔出你感興趣的元素

下面的代碼創建類型的字典列表的列表(即表/數據/信息):

tables = [] 
myXML = ET.fromstring(fileAsString) 
for table in myXML.findall('./eventTable'): 
    transactions = [] 
    tables.append(transactions) 
    for transaction in table.findall('./eventTransaction'): 
     info = {} 
     for element in table.findall('.//*[value]'): 
      info[element.tag] = element.find('./value').text or '' 
     coding = transaction.find('./eventCoding') 
     if coding is not None: 
      for tag in 'eventType', 'eventCode': 
       element = coding.find('./%s' % tag) 
       if element is not None: 
        info[tag] = element.text or '' 
      for index, element in enumerate(coding.findall('./footnoteId')): 
       info['eventCoding_FTNT_%d' % index] = element.get('id', '') 
     if info: 
      transactions.append(info) 

輸出:

[[{'eventCode': 'A', 
    'eventCoding_FTNT_0': 'F1', 
    'eventCoding_FTNT_1': 'F2', 
    'eventCycled': '', 
    'eventDate': '2003-12-31', 
    'eventTitle': 'Some Event', 
    'eventType': '47', 
    'eventVoltage': '40000'}]] 
+0

謝謝你的見解 – PyNEwbie

+0

@exhumoro最後一個太蹩腳了 - 非常感謝你花時間。我可以從這個例子中學到很多答案 – PyNEwbie

+0

@PyNEwbie。 NP - 很高興幫助!順便說一下,爲了保持一致性,我在整個示例中使用了xpath語法,但是可以通過僅使用標記名來替換'./ tagname'來簡化它。真正需要的xpath的唯一用途是'.//* [value]',它遞歸地搜索包含'value'子元素的元素。 – ekhumoro

相關問題