Skip to main content
 首页 » 编程设计

Python XML 解析示例

2025年05月04日11dflying

我需要简化 XML 中的数据,以便能够将其作为单个表格(即 csv)读取。我找到了一些带有 ElementTree 的 Python 2.7 示例,但到目前为止,我无法对其进行调整以使其在树的更下方工作,因此不仅仅是收集最高级别的元素。但是为每一行重复最高级别的元素并获取其余元素。

我知道我可以而且应该 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> 

所以我希望看到一个只包含 FUNDS 数据的表格,但是:

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

等等

在 csv 文件中,我只是不想破坏格式。

请注意 perfMonth 是关键,代码只是没有用数据示例包装在上面的框中。

请您参考如下方法:

我用了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 有一个不匹配的标签。您可能需要先解决这个问题。