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

lxml目标接口拆分非ASCII字符,如何获取完整字符串?

解决lxml解析含非ASCII字符文本时的拆分问题

测试文件 test.xml

<?xml version="1.0" encoding="UTF-8"?>
<list>
  <entry>data</entry>
  <entry>Łódź</entry>
  <entry>data Łódź</entry>
</list>

原解析脚本

from lxml import etree

class ParseTarget:
    def __init__(self):
        self.entries = []
    def start(self, tag, attrib):
        pass
    def end(self, tag):
        pass
    def data(self, data):
        str = data.strip()
        if str != '':
            self.entries.append(data)
    def close(self):
        # Reset parser
        entries = self.entries
        self.entries = []
        # And return results
        return entries

target = etree.XMLParser(target=ParseTarget(),
                         # Including/removing this makes no difference
                         encoding='UTF-8')

tree = etree.parse("./test.xml", target)

# 预期结果:
# ['data', 'Łódź', 'data Łódź']
# 实际结果:
# ['data', 'Łódź', 'data ', 'Łódź']

问题说明

运行上述脚本后,预期得到3个元素的列表,但实际得到4个元素。原因是lxml的SAX风格解析器会将包含非ASCII字符(且开头有ASCII字符)的文本拆分为多个片段,多次调用data方法传递,导致原本属于同一个<entry>的文本被拆成两个元素存入结果列表。

解决方案

核心思路是维护一个临时缓冲区,拼接同一个文本节点的所有分段内容,直到元素结束时再统一处理:

from lxml import etree

class ParseTarget:
    def __init__(self):
        self.entries = []
        self.current_text = []  # 临时缓冲区,用于拼接分段文本

    def start(self, tag, attrib):
        # 进入新元素时重置缓冲区
        self.current_text = []

    def end(self, tag):
        # 离开元素时,拼接完整文本并处理
        full_text = ''.join(self.current_text).strip()
        if full_text:
            self.entries.append(full_text)
        self.current_text = []

    def data(self, data):
        # 仅将文本片段追加到缓冲区,不直接存入结果
        self.current_text.append(data)

    def close(self):
        entries = self.entries
        self.entries = []
        return entries

target = etree.XMLParser(target=ParseTarget(), encoding='UTF-8')
tree = etree.parse("./test.xml", target)
# 此时tree的值为预期的 ['data', 'Łódź', 'data Łódź']

关键修改点

  1. 新增current_text列表作为临时缓冲区,接收每次data方法传递的文本片段。
  2. start方法中重置缓冲区,确保每个元素的文本收集从头开始。
  3. end方法中完成文本拼接、去空处理后,再将完整文本加入结果列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:52:14