如何从xml数据中提取数据并保存在excel文件中

问题描述 投票:0回答:1

我有一个

.xml
文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
  <Act  bind="a" >
    <Key frame="32" value="1" />
    <Key frame="62" value="8" />
    <Key frame="106" value="14" />    
  </>
  <Act  bind="b" >
    <Key frame="32" value="1" />
    <Key frame="62" value="30" />
    <Key frame="106" value="30" />    
  </>
  <Act  bind="c" >
    <Key frame="28" value="81" />
    <Key frame="58" value="78" />
    <Key frame="102" value="78" />    
  </>
</>

如何编写将这些值保存在 excel 文件中的脚本,其中我有与 binds 一样多的列和与 frames 一样多的行。此外,帧按升序排序,如果绑定没有帧值,则插入 0。像下面这样的东西:

      a         b         c   
28    0         0         81
32    1         1         0
58    0         0         78
62    8         30        0
102   0         0         78
106   14        30        0

非常感谢任何帮助。

xml-parsing
1个回答
0
投票

正如@GillesQuénot所说,这真的不是在SO上提问的方式,所以请下次尝试做得更好。

尽管如此,这是一项足够有趣的作业,所以我试图解决它。首先,问题中的 xml 格式不正确,所以我将它(见下文)修复为我认为应该的格式。

一旦我们超过了那个,它就变成了一个有点杂技的任务,需要使用 lxml、xpath、列表理解、f-strings 和几个 pandas 方法——但它是可行的。 [注意那些可能想知道的人 - FWIW,我尝试但未能使用

pandas.read_xml()
实现同样的事情]。

所以一起:

#your xml, fixed
source = """<?xml version="1.0" encoding="UTF-8"?>
<root>
   <Act bind="a">
      <Key frame="32" value="1" />
      <Key frame="62" value="8" />
      <Key frame="106" value="14" />
   </Act>
   <Act bind="b">
      <Key frame="32" value="1" />
      <Key frame="62" value="30" />
      <Key frame="106" value="30" />
   </Act>
   <Act bind="c">
      <Key frame="28" value="81" />
      <Key frame="58" value="78" />
      <Key frame="102" value="78" />
   </Act>
</root>
"""
from lxml import etree
doc = etree.XML(source.encode())
#you need to convert to int so it can be properly sorted later:
frames = [int(frm) for frm in doc.xpath('//Key/@frame')]
#find the unique values and sort them
uni_frames = sorted(set(frames))

#start preparing your dataframe
rows, cols = [],[]
for act in doc.xpath('//Act'):
    #get the column names
    cols.append(act.xpath('./@bind')[0])
    row = []
    for frame in uni_frames:
        #get the frame values
        val = f'.//Key[@frame={frame}]/@value'
        entry = act.xpath(val)[0] if act.xpath(val) else "0"
        row.append(entry)
    rows.append(row)

#now assemble the dataframe itself
df = pd.DataFrame(rows)
df = df.transpose()
#rename the columns
df.columns = cols
#finally, insert the first column
df.insert(loc = 0,
          column = 'frame',
          value = uni_frames)
df

输出:

  frame a   b   c
0   28  0   0   81
1   32  1   1   0
2   58  0   0   78
3   62  8   30  0
4   102 0   0   78
5   106 14  30  0

现在您有了数据框,您可以使用其他 pandas 方法保存到 Excel 到 CSV

© www.soinside.com 2019 - 2024. All rights reserved.