如何用Python将指定ISO 4217 XML文件转换为CSV表格?
问题描述
我需要将ISO 4217标准的XML文件转换为包含CtryNm、CcyNm、Ccy、CcyNbr、CcyMnrUnts这5列的CSV表格。该XML文件的结构片段如下:
<ISO_4217 Pblshd="2024-01-01"> <CcyTbl> <CcyNtry> <CtryNm>AFGHANISTAN</CtryNm> <CcyNm>Afghani</CcyNm> <Ccy>AFN</Ccy> <CcyNbr>971</CcyNbr> <CcyMnrUnts>2</CcyMnrUnts> </CcyNtry> <CcyNtry> <CtryNm>ZZ07_No_Currency</CtryNm> <CcyNm>The codes assigned for transactions where no currency is involved</CcyNm> <Ccy>XXX</Ccy> <CcyNbr>999</CcyNbr> <CcyMnrUnts>N.A.</CcyMnrUnts> </CcyNtry> </CcyTbl> </ISO_4217>
我尝试了以下代码,但运行后生成的是空白文件,请问哪里出错了?或者有没有更简便的方法将该XML数据转换为DataFrame?
def parse_xml(xml_file): tree = ET.parse(xml_file) root = tree.getroot() return root def extract_data(root): data = [] for record in root.findall('CcyNtry'): row = {} for field in record: row[field.tag] = field.text data.append(row) return data def main(xml_file, csv_file): root = parse_xml(xml_file) data = extract_data(root) df = to_dataframe(data) to_csv(df, csv_file) main(countries, 'output.csv')
问题分析与解决方案
错误原因
- 节点路径错误:XML中
CcyNtry嵌套在CcyTbl节点下,直接用root.findall('CcyNtry')无法定位到目标节点,导致没有数据被提取。 - 模块缺失与未定义内容:代码未导入
xml.etree.ElementTree(对应ET)和pandas模块;to_dataframe、to_csv未明确是pandas的方法;countries变量未赋值为XML文件的实际路径。
修正后的手动解析代码
import xml.etree.ElementTree as ET import pandas as pd def parse_xml(xml_file): tree = ET.parse(xml_file) root = tree.getroot() return root def extract_data(root): data = [] # 正确定位到CcyTbl下的CcyNtry节点 for record in root.findall('./CcyTbl/CcyNtry'): row = {} # 只提取指定的5个字段,避免冗余数据 target_fields = ['CtryNm', 'CcyNm', 'Ccy', 'CcyNbr', 'CcyMnrUnts'] for field in target_fields: element = record.find(field) row[field] = element.text if element is not None else '' data.append(row) return data def main(xml_file, csv_file): root = parse_xml(xml_file) data = extract_data(root) df = pd.DataFrame(data) df.to_csv(csv_file, index=False) # 替换为你的XML文件实际路径 main('list-one.xml', 'output.csv')
更简便的方法:使用pandas内置的read_xml
从pandas 1.3.0版本开始,支持直接读取XML文件,无需手动遍历节点,代码更简洁:
import pandas as pd # 读取XML并指定目标节点和字段 df = pd.read_xml( 'list-one.xml', xpath='./CcyTbl/CcyNtry', usecols=['CtryNm', 'CcyNm', 'Ccy', 'CcyNbr', 'CcyMnrUnts'] ) # 保存为CSV df.to_csv('output.csv', index=False)
内容的提问来源于stack exchange,提问作者user23486108
相关产品推荐
相关产品推荐

