如何提取XML含<br>及子标签的文本并转换为DataFrame?
解决方案
1. 完整提取标签内的所有文本
要保留<br>和<exposant>相关内容,不能直接取标签的text属性,得递归提取所有子节点的文本内容(包括嵌套标签)。以下是两种常用XML解析库的实现示例:
基于lxml的实现
from lxml import etree import pandas as pd def extract_full_text(element): # 递归拼接所有非空文本片段 text_parts = [] for segment in element.itertext(): trimmed = segment.strip() if trimmed: text_parts.append(trimmed) return ' '.join(text_parts) # 解析XML文件 tree = etree.parse("你的XML文件路径.xml") root = tree.getroot() # 提取发言人及对应完整发言 data = [] # 这里的".//votant"需替换为XML中包含nom和texte的父节点路径 for speaker_node in root.findall(".//votant"): # 提取发言人姓名 nom_node = speaker_node.find("nom") nom = nom_node.text.strip() if nom_node is not None else "" # 提取完整发言文本 texte_node = speaker_node.find("texte") full_texte = extract_full_text(texte_node) if texte_node is not None else "" data.append({"nom": nom, "texte": full_texte})
基于xml.etree.ElementTree的实现
import xml.etree.ElementTree as ET import pandas as pd def extract_full_text(element): # 递归拼接当前节点文本、子节点文本及子节点尾文本 text = element.text or "" for child in element: text += extract_full_text(child) if child.tail: text += child.tail return text.strip() # 解析XML文件 tree = ET.parse("你的XML文件路径.xml") root = tree.getroot() # 提取数据逻辑同上 data = [] for speaker_node in root.findall(".//votant"): nom_node = speaker_node.find("nom") nom = nom_node.text.strip() if nom_node is not None else "" texte_node = speaker_node.find("texte") full_texte = extract_full_text(texte_node) if texte_node is not None else "" data.append({"nom": nom, "texte": full_texte})
2. 宽表转长表实现一一对应
如果原始提取结果是宽表结构(比如一行包含多个发言人的nom和texte列,如nom1、texte1、nom2、texte2),可以用pd.melt转换为长表:
# 假设wide_df是你的宽表DataFrame wide_df = pd.DataFrame(data) # 拆分nom和texte列组 nom_cols = [col for col in wide_df.columns if col.startswith("nom")] texte_cols = [col for col in wide_df.columns if col.startswith("texte")] # 分别转换nom和texte列 df_nom = pd.melt(wide_df, value_vars=nom_cols, var_name="nom_col", value_name="nom") df_texte = pd.melt(wide_df, value_vars=texte_cols, var_name="texte_col", value_name="texte") # 匹配nom和texte的对应关系(通过列名中的数字索引) df_nom["idx"] = df_nom["nom_col"].str.extract(r"(\d+)").astype(int) df_texte["idx"] = df_texte["texte_col"].str.extract(r"(\d+)").astype(int) # 合并并清理结果 long_df = pd.merge(df_nom, df_texte, on="idx").drop(columns=["nom_col", "texte_col", "idx"]) # 过滤空值行 long_df = long_df.dropna(subset=["nom", "texte"])
关键注意事项
- 代码中的标签路径(如
.//votant、nom、texte)需替换为你XML文件的实际结构 - 若需要保留
<br>的换行效果,可在extract_full_text中判断标签类型,遇到<br>时拼接\n而非普通空格 - 若要保留
<exposant>的上标格式,可在递归提取时给对应文本添加标记(如^文本^),后续按需处理
内容的提问来源于stack exchange,提问作者MG Fern
相关产品推荐
相关产品推荐

