Python解析旧版Excel XML文件问题求助
解析旧版Excel XML(SpreadsheetML)并转为DataFrame
我之前也碰到过这种旧版的Microsoft Office Spreadsheet XML格式文件的解析问题——xlrd确实不支持这类格式,手动用XML解析库的时候又容易因为命名空间处理不当失败。给你两个可行的解决方案,都能直接把文件转换成pandas DataFrame:
方案一:用pandas的read_xml直接处理(推荐)
pandas的read_xml支持处理带命名空间的XML,只需指定命名空间和对应的XPath即可:
import pandas as pd # 定义XML中使用的命名空间 namespaces = {'ss': 'urn:schemas-microsoft-com:office:spreadsheet'} # 读取XML文件,定位到目标工作表(这里是"Holdings")下的所有行 df_rows = pd.read_xml( "your_file.xml", namespaces=namespaces, xpath='//ss:Worksheet[@ss:Name="Holdings"]/ss:Table/ss:Row' ) # 提取每行中单元格的实际数据 def get_cell_values(row): cells = row["Cell"] # 处理单个单元格的情况(转为列表统一处理) if not isinstance(cells, list): cells = [cells] # 提取每个单元格内的Data文本内容 return [ cell["Data"]["#text"] if isinstance(cell["Data"], dict) else cell["Data"] for cell in cells ] # 应用函数提取每行数据,再展开为多列 df_rows["cell_data"] = df_rows.apply(get_cell_values, axis=1) final_df = pd.DataFrame(df_rows["cell_data"].tolist()) # 如果需要转成CSV,直接执行下面的代码 # final_df.to_csv("output.csv", index=False, header=False) print(final_df)
代码说明:
- 首先通过
namespaces参数声明XML里的ss命名空间,避免XPath找不到元素 - 用XPath精准定位到目标工作表(
Holdings)下的所有行 - 因为部分行可能只有单个单元格,需要统一转成列表处理,再提取每个单元格的
Data文本 - 最后把提取到的每行数据展开为多列,得到标准的DataFrame
方案二:用xml.etree.ElementTree手动解析
如果pandas的方法不符合需求,也可以用Python内置的XML库手动处理,核心是正确处理命名空间:
import xml.etree.ElementTree as ET import pandas as pd # 注册命名空间,方便后续使用短名查找元素 ET.register_namespace('ss', 'urn:schemas-microsoft-com:office:spreadsheet') tree = ET.parse("your_file.xml") root = tree.getroot() # 定位到目标工作表和表格 target_worksheet = root.find( './/ss:Worksheet[@ss:Name="Holdings"]', namespaces={'ss': 'urn:schemas-microsoft-com:office:spreadsheet'} ) table = target_worksheet.find('ss:Table', namespaces={'ss': 'urn:schemas-microsoft-com:office:spreadsheet'}) # 遍历所有行,提取单元格数据 all_data = [] for row in table.findall('ss:Row', namespaces={'ss': 'urn:schemas-microsoft-com:office:spreadsheet'}): row_values = [] for cell in row.findall('ss:Cell', namespaces={'ss': 'urn:schemas-microsoft-com:office:spreadsheet'}): data_elem = cell.find('ss:Data', namespaces={'ss': 'urn:schemas-microsoft-com:office:spreadsheet'}) row_values.append(data_elem.text if data_elem is not None else None) all_data.append(row_values) # 转换为DataFrame final_df = pd.DataFrame(all_data) # 转CSV的话执行: # final_df.to_csv("output.csv", index=False, header=False) print(final_df)
代码说明:
- 先注册命名空间,避免查找元素时因为前缀问题失败
- 逐层定位到工作表、表格,再遍历每一行和每个单元格
- 提取每个
ss:Data元素的文本内容,收集成二维列表后转成DataFrame
这两个方案都能解决你遇到的解析问题,直接生成DataFrame,也可以轻松导出为CSV文件。
内容的提问来源于stack exchange,提问作者Hayton Leung
相关产品推荐
相关产品推荐

