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