2

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

4

1 回答 1

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

于 2013-07-19T11:54:15.510 回答