我目前正在将复杂的XML文件转换为csv或pandas df。 我对xml数据格式零经验,我在网上找到的所有代码建议都对我不起作用。有人可以帮我吗?
数据中有很多不需要的元素,因此在此不再赘述。
出于隐私方面的考虑,我不会在此处上传原始数据,但会分享结构的外观。
<RefData>
<Attributes>
<Id>1011</Id>
<FullName>xxxx</FullName>
<ShortName>xx</ShortName>
<Country>UK</Country>
<Currency>GBP</Currency>
</Attributes>
<PolicyID>000</PolicyID>
<TradeDetails>
<UniqueTradeId>000</UniqueTradeId>
<Booking>UK</Booking>
<Date>12/2/2019</Date>
</TradeDetails>
</RefData>
<RefData>
<Attributes>
<Id>1012</Id>
<FullName>xxx2</FullName>
<ShortName>x2</ShortName>
<Country>UK</Country>
<Currency>GBP</Currency>
</Attributes>
<PolicyID>002</PolicyID>
<TradeDetails>
<UniqueTradeId>0022</UniqueTradeId>
<Booking>UK</Booking>
<Date>12/3/2019</Date>
</TradeDetails>
</RefData>
我需要标记中的所有内容。
理想情况下,我希望标题和输出看起来像这样:
衷心感谢您能为此提供的任何帮助。谢谢你。
答案 0 :(得分:3)
有关输入XML文件的一项更正:它必须包含 单个主元素(任何名称),并在其中包含您的 RefData 元素。
因此输入文件实际上包含:
<Main>
<RefData>
...
</RefData>
<RefData>
...
</RefData>
</Main>
要处理输入的XML文件,可以使用 lxml 包,以便导入 它开始于:
from lxml import etree as et
然后我注意到您实际上不需要整个已解析的XML树, 因此通常采用的方案是:
所以我的代码如下:
rows = []
for _, elem in et.iterparse('RefData.xml', tag='RefData'):
rows.append({'id': elem.findtext('Attributes/Id'),
'fullname': elem.findtext('Attributes/FullName'),
'shortname': elem.findtext('Attributes/ShortName'),
'country': elem.findtext('Attributes/Country'),
'currency': elem.findtext('Attributes/Currency'),
'Policy ID': elem.findtext('PolicyID'),
'UniqueTradeId': elem.findtext('TradeDetails/UniqueTradeId'),
'Booking': elem.findtext('TradeDetails/Booking'),
'Date': elem.findtext('TradeDetails/Date')
})
elem.clear()
elem.getparent().remove(elem)
df = pd.DataFrame(rows)
要完全理解详细信息,请在Web上搜索 lxml 的描述,然后 每种方法。
对于您的样本数据,结果为:
id fullname shortname country currency Policy ID UniqueTradeId Booking Date
0 1011 xxxx xx UK GBP 000 000 UK 12/2/2019
1 1012 xxx2 x2 UK GBP 002 0022 UK 12/3/2019
可能要执行的最后一步是将上述DataFrame保存为CSV文件 文件,但我想您知道该怎么做。
答案 1 :(得分:1)
使用lxml和xpath的另一种方法:
from lxml import etree
dat = """[your FIXED xml]"""
doc = etree.fromstring(dat)
columns = []
rows = []
to_delete = ["TradeDetails",'Attributes']
body = doc.xpath('.//RefData')
for el in body[0].xpath('.//*'):
columns.append(el.tag)
for b in body:
items = b.xpath('.//*')
row = []
for item in items:
if item.tag not in to_delete:
row.append(item.text)
rows.append(row)
for col in to_delete:
if col in columns:
columns.remove(col)
pd.DataFrame(rows,columns=columns)
输出是您问题中指示的数据框。