将XML中的变量提取到Pandas中



我正在将XML变量解析为pandas数据帧。XML文件看起来像(此XML文件已简化用于演示(

<Instrm>
<Rcrd>
<FinPpt>
<Id>BT0007YSAWK</Id>
<FullNm>Turbo Car</FullNm>
<Ccy>EUR</Ccy>
<Cmmdty>false</Cmmdty>
</FinPpt>
<Issr>529900M2F7D5795H1A49</Issr>
<Attrbts>
<Authrty>US</Authrty>
<Prd>
<Dt>2002-03-20</Dt>
</Prd>
<Ven>NYSE</Ven>
</Attrbts >
</Rcrd>
</Instrm>
<Instrm>
<Rcrd>
<FinPpt>
<Id>BX0009YNOYK</Id>
<FullNm>Turbo truk</FullNm>
<Ccy>EUR</Ccy>
<Cmmdty>false</Cmmdty>
</FinPpt>
<Issr>58888M2F7D579536J4</Issr>
<Attrbts>
<Authrty>UK</Authrty>
<Prd>
<Dt>2002-04-21</Dt>
</Prd>
<Ven>BOX</Ven>
</Attrbts >
</Rcrd>
</Instrm>
...

我试图将这个XML文件解析为一个数据帧,其中的属性是列名,如下所示:

Id          FullNm     Ccy   Cmmdty           Issr              Authrty      Dt         Ven   
BT0007YSAWK     Turbo Car   EUR   false    529900M2F7D5795H1A49       US       2002-03-20    NYSE
BX0009YNOYK     Turbo truk  EUR   false    58888M2F7D579536J4         UK       2002-04-21    BOX
.....            ......    

但我还是不知道如何在我审查了一些帖子之后。我所能做的就是在列表中提取ID,比如

import xml.etree.ElementTree as ET
import pandas as pd
import sys
tree = ET.parse('sample.xml')
root = tree.getroot()
report = root[1][0][0]
records = report.findall('Instrm')
ids = []
for r in records:
ids.append(r[0][0][0].text)
print(ids[0:100])

out:

[BT0007YSAWK, BX0009YNOYK, …….]

我不太明白如何在这里使用"节点"。有人能帮忙吗?非常感谢。

假设发布的XML中有一个<root>节点而没有名称空间,请考虑通过列表/dict理解构建一个字典,并组合解析到所需节点的子字典(在Python 3.5+中可用(。然后在返回的字典列表中调用DataFrame()构造函数。

data = [{**{el.tag:el.text.strip() for el in r.findall('FinPpt/*')},
**{el.tag:el.text.strip() for el in r.findall('Issr')},
**{el.tag:el.text.strip() for el in r.findall('Attrbts/*')},
**{el.tag:el.text.strip() for el in r.findall('Attrbts/Prd/*')} 
} for r in root.findall('Instrm/Rcrd')]

df = pd.DataFrame(data)

要在不进行转换的情况下获取目标数据,请使用xml解析器(如lxml(和xpath。

大致如下:[注意,您必须用根元素包装xml]

string = """
<doc>
[your xml above]
</doc>
"""
from lxml import etree
doc = etree.XML(string)
insts = doc.xpath('//Instrm')
for inst in insts:
f_nams = inst.xpath('//FullNm')
ccys = inst.xpath('//Ccy')
cmds = inst.xpath('//Cmmdty')
issuers = inst.xpath('//Issr')
for a,b,c,d in zip(f_nams,ccys,cmds,issuers):
print(a.text,b.text,c.text,d.text)

输出:

Turbo Car EUR false 529900M2F7D5795H1A49
Turbo truk EUR false 58888M2F7D579536J4

最新更新