You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python etree.ElementTree提取含HTML标签的XML文本时出现截断问题

核心原因

XML元素内嵌<i>这类子标签时,文本会被拆分存储:父元素的text存储第一个子标签前的内容,内嵌子标签的text存储标签包裹的内容,子标签的tail存储标签结束后到父元素闭合前的内容,直接读取父元素的.text只能拿到第一部分文本。

方案1:使用标准库xml.etree.ElementTree实现

写一个递归拼接函数处理所有文本节点:

import xml.etree.ElementTree as ET

def get_full_text(element):
    full_text = []
    if element.text:
        full_text.append(element.text)
    for child in element:
        full_text.append(get_full_text(child))
        if child.tail:
            full_text.append(child.tail)
    return ''.join(full_text)

# 业务逻辑改造
xmldata = 'directory/to/data.xml'
tree = ET.parse(xmldata)
root = tree.getroot()

abstracts = {}
titles = {}

# 遍历每一篇独立文章节点,根据实际XML结构调整标签名
for idx, article in enumerate(root.findall('PubmedArticle')):
    # 提取完整标题
    title_elem = article.find('.//ArticleTitle')
    if title_elem is not None:
        titles[idx] = get_full_text(title_elem)
    # 提取完整摘要
    abstract_elem = article.find('.//AbstractText')
    if abstract_elem is not None:
        abstracts[idx] = get_full_text(abstract_elem)

方案2:使用lxml实现(更简洁)

之前用lxml出错是因为用了全局路径//AbstractText匹配了文档所有摘要节点,改成相对路径匹配单篇文章下的节点,再用string()方法自动拼接所有内嵌文本即可:

from lxml import etree

xmldata = 'directory/to/data.xml'
tree = etree.parse(xmldata)

abstracts = {}
titles = {}

# 先匹配所有独立文章节点
for idx, article in enumerate(tree.xpath('//PubmedArticle')):
    # 匹配当前文章下的标题,自动拼接所有文本
    title = article.xpath('.//ArticleTitle')[0].xpath('string(.)')
    titles[idx] = title
    # 匹配当前文章下的摘要
    abstract = article.xpath('.//AbstractText')[0].xpath('string(.)')
    abstracts[idx] = abstract

两种方案都可以保留原始文本的完整内容,不会丢失内嵌标签包裹的文本。

内容的提问来源于stack exchange,提问作者deardirestraits

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 03:48:00