【问题标题】:Python XML parsing examplePython XML 解析示例
【发布时间】:2013-07-18 15:43:09
【问题描述】:

我需要简化 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 是关键,代码只是没有用数据示例包装在上面的框中。

【问题讨论】:

    标签: python xml csv python-2.7 xml-parsing


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

    【讨论】:

    • 谢谢,@falsetru。可悲的是,我无法在需要完成此操作的地方使用 lxml,但也许总体思路仍然适用。
    • @László,您也可以使用 xml.etree.ElementTree,因为我这里没有使用 lxml 特定功能。
    猜你喜欢
    • 2011-12-18
    • 2010-12-19
    • 2012-01-29
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 1970-01-01
    相关资源
    最近更新 更多