如何将大型XML文件转换为目标格式的Pandas DataFrame?
XML转DataFrame的修正方案
问题说明
需要将带命名空间的嵌套XML文件转换为指定结构的DataFrame,当前代码仅遍历根节点直接子节点,未处理深层嵌套结构,也未适配XML命名空间,导致输出结果不符合预期。
XML示例
<?xml version='1.0' encoding='UTF-8'?> <compteRendu xmlns="http://schemas.assemblee-nationale.fr/referentiel"> <uid>CRSANR5L15S2017E1N001</uid> <metadonnees> <day>04 juillet 2017</day> <legislature>15</legislature> <sommaire> <president id_syceron="981337">Présidence de M. François de Rugy</president> </sommaire> </metadonnees> <contenu> <quantiemes> <journee>Séance du mardi 04 juillet 2017</journee> <session>Première session extraordinaire 2017</session> </quantiemes> <point nivpoint="1" valeur_ptsodj="2" ordinal_prise="1" id_preparation="819547" ordre_absolu_seance="8" code_grammaire="TITRE_TEXTE_DISCUSSION" code_style="Titre" code_parole="" sommaire="1" id_syceron="981344" valeur=""> <orateurs/> <texte>Déclaration de...</texte> <paragraphe valeur_ptsodj="2" ordinal_prise="1" id_preparation="819550" ordre_absolu_seance="11" id_acteur="PA345619" id_mandat="-1" id_nomination_oe="PM725692" id_nomination_op="-1" code_grammaire="DEBAT_1_10" code_style="NORMAL" code_parole="PAROLE_1_2" sommaire="1" id_syceron="981347" valeur=""> <orateurs> <orateur> <nom>M. Edouard Philippe</nom> <id>345619</id> <qualite>Premier ministre</qualite> </orateur> </orateurs> <texte>Monsieur le président... <italique>(Applaudissements sur les bancs des groupes REM et MODEM.)</italique></texte> </paragraphe> </point> </contenu> </compteRendu>
期望输出DataFrame
day legislature texte nom texte2 04 juillet 2017 15 Déclaration de... Edouard Philippe Monsieur le président...
当前代码及错误输出
当前代码未处理嵌套节点与命名空间,导致输出缺失关键数据:
import pandas as pd import xml.etree.ElementTree as et etree=et.parse("myfile.xml") root=etree.getroot() A=[] for ele in root: B={} for i in list(ele): B.update({i.tag: i.text}) A.append(B) df=pd.DataFrame(A)
错误输出:
day legislature sommaire quantiemes point 04 juillet 2017 15 \n NaN NaN
修正代码
import pandas as pd import xml.etree.ElementTree as et import re # 定义XML命名空间,必须指定才能定位标签 namespace = {'ns': 'http://schemas.assemblee-nationale.fr/referentiel'} etree = et.parse("myfile.xml") root = etree.getroot() data_list = [] # 提取元数据部分 metadonnees = root.find('ns:metadonnees', namespace) day_val = metadonnees.find('ns:day', namespace).text legislature_val = metadonnees.find('ns:legislature', namespace).text # 遍历所有point节点(支持多段落场景) points = root.findall('ns:contenu/ns:point', namespace) for point in points: # 提取point下的标题文本 texte_val = point.find('ns:texte', namespace).text # 定位paragraphe节点 paragraphe = point.find('ns:paragraphe', namespace) # 提取发言人姓名 orateur_nom = paragraphe.find('ns:orateurs/ns:orateur/ns:nom', namespace).text # 提取发言文本并清理XML标签 texte2_val = paragraphe.find('ns:texte', namespace).text texte2_val = re.sub(r'<[^>]+>', '', texte2_val) # 移除所有XML标签 # 整理成字典加入列表 data_list.append({ 'day': day_val, 'legislature': legislature_val, 'texte': texte_val, 'nom': orateur_nom, 'texte2': texte2_val }) # 生成DataFrame df = pd.DataFrame(data_list) print(df)
代码说明
- 命名空间适配:XML带有默认命名空间,必须通过
namespace字典声明,才能用find/findall正确定位标签。 - 深层节点提取:逐层遍历嵌套节点,从
metadonnees提取基础信息,从contenu下的point和paragraphe提取文本与发言人数据。 - 文本清理:用正则表达式移除发言文本中的XML格式标签,若需保留原格式可跳过此步骤。
- 批量兼容:通过
findall遍历所有point节点,支持包含多个段落的大型XML文件转换。
内容的提问来源于stack exchange,提问作者MG Fern
相关产品推荐
相关产品推荐

