2013-07-19 77 views
2

我需要簡化XML中的數據以便能夠將其作爲單個表進行讀取,從而實現csv。我發現了ElementTree的一些Python 2.7實例,但到目前爲止,我無法調整它以在樹上繼續工作,因此不僅收集最高級別的元素。但重複他們每行的最高級元素,並獲得其餘的。Python XML解析示例

我知道我可以也應該RTFM,但我需要儘快解決問題。

也許鏈接的xsd文件可以幫助嗎?

我的數據看起來像

<!-- MoneyMate (tm) XMLPerfs Application version 1.0.1.1 - Copyright © 2000 MoneyMate Limited. All Rights Reserved. MoneyMate ® --> 
<!-- Discrete Perfs for 180 periods for Monthly frequency --> 
<MONEYMATE_XML_FEED xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://mmia2.moneymate.com/xml/MoneyMateComplete.xsd" version="1.0" calcCurrency="SEK"> 
<TYPES> 
<TYPE typeCountry="SE" typeId="85" typeName="string" calcToDate="2013-07-16"> 
<COMPANIES> 
<COMPANY companyId="25000068" companyName="string"/> 
… 

<CATEGORIES> 
<CATEGORY categoryId="1101" categoryName="Aktie -- Asien"> 
<FUNDS> 
<FUND fundId="6201" fundName="string" fundCurrency="GBP" fundCompanyId="25000068"><PERFORMANCES><MONTHLYPERFS><PERFORMANCEMONTH perfEndMonth="2006-05-31" perfMonth="-0.087670"/><PERFORMANCEMONTH> 
… 
</PERFORMANCES></FUND></FUNDS> 
</CATEGORY> 
<CATEGORY categoryId="13" categoryName="Räntefonder"> 
<FUNDS></FUNDS> 
</CATEGORY> 
</CATEGORIES> 
</TYPE> 
</TYPES> 
</MONEYMATE_XML_FEED> 

因此,我希望看到一個表,只從基金的數據,但:

fundid fundName fundCurrency fundCompanyId perfEndMonth perfMonth 
…  …   …    …    …    … 

而且在csv文件,我只是不想打破格式。

請注意,perfMonth是關鍵,代碼只是沒有包裝在上面的數據示例框中。

回答

1

我用lxml

import csv 

import lxml.etree 

x = u'''<!-- MoneyMate (tm) XMLPerfs Application version 1.0.1.1 - Copyright 2000 MoneyMate Limited. All Rights Reserved. MoneyMate --> 
<!-- Discrete Perfs for 180 periods for Monthly frequency --> 
<MONEYMATE_XML_FEED xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://mmia2.moneymate.com/xml/MoneyMateComplete.xsd" version="1.0" calcCurrency="SEK"> 
    <TYPES> 
     <TYPE typeCountry="SE" typeId="85" typeName="string" calcToDate="2013-07-16"> 
      <COMPANIES> 
       <COMPANY companyId="25000068" companyName="string"/> 
       <CATEGORIES> 
        <CATEGORY categoryId="1101" categoryName="Aktie -- Asien"> 
         <FUNDS> 
          <FUND fundId="6201" fundName="string" fundCurrency="GBP" fundCompanyId="25000068"> 
           <PERFORMANCES> 
            <MONTHLYPERFS> 
             <PERFORMANCEMONTH perfEndMonth="2006-05-31" perfMonth="-0.087670"/> 
            </MONTHLYPERFS> 
           </PERFORMANCES> 
          </FUND> 
         </FUNDS> 
        </CATEGORY> 
        <CATEGORY categoryId="13" categoryName="Rntefonder"> 
         <FUNDS></FUNDS> 
        </CATEGORY> 
       </CATEGORIES> 
      </COMPANIES> 
     </TYPE> 
    </TYPES> 
</MONEYMATE_XML_FEED> 
''' 

with open('output.csv', 'w') as f: 
    writer = csv.writer(f) 
    writer.writerow(('fundid', 'fundName', 'fundCurrency', 'fundCompanyId', 'perfEndMonth', 'perfMonth')) 
    root = lxml.etree.fromstring(x) 
    for fund in root.iter('FUND'): 
     perf = fund.find('.//PERFORMANCEMONTH') 
     row = fund.get('fundId'), fund.get('fundName'), fund.get('fundCurrency'), fund.get('fundCompanyId'), perf.get('perfEndMonth'), perf.get('perfMonth') 
     writer.writerow(row) 

注意

的問題給定的XML具有不匹配的標籤。您可能需要先解決這個問題。

+0

謝謝@falsetru。可悲的是,我不能在需要完成這項工作的地方使用lxml,但也許總體思路仍然適用。 –

+0

@László,你也可以使用xml.etree.ElementTree,因爲我沒有在這裏使用lxml特定的函數。 – falsetru