lxml创建CDATA元素调用tostring序列化报无法序列化CDATA对象错误
问题根因
报错是因为你混用了两套完全不兼容的XML处理库:
- 你代码里导入的
ET是Python标准库自带的xml.etree.cElementTree - 你使用的
CDATA是第三方库lxml的专属数据类型
标准库的ElementTree实现没有针对lxml CDATA类型的序列化逻辑,遇到不识别的对象类型就会直接抛出序列化失败的异常。
修复方案
如果需要使用CDATA能力,全程使用lxml提供的etree接口即可,不要和标准库的XML模块混用,同时序列化时注意加参数保留CDATA格式:
from lxml import etree as ET from lxml.etree import CDATA root = ET.Element('rss') root.set("version", "2.0") description = ET.SubElement(root, "description") description.text = CDATA('test') # 注意要加strip_cdata=False,否则lxml默认会把CDATA转成普通转义文本,不会保留CDATA标记 xml_str = ET.tostring(root, xml_declaration=True, encoding='utf-8', strip_cdata=False).decode() print(xml_str)
运行后可以正常输出带CDATA标记的XML内容:
<?xml version='1.0' encoding='utf-8'?> <rss version="2.0"><description><![CDATA[test]]></description></rss>
额外注意事项
- lxml和标准库ElementTree的API看起来高度相似,但底层元素实现、序列化逻辑完全独立,不要跨库传递元素对象、特殊类型值,否则必然出现兼容性问题。
- 如果坚持要用标准库的ElementTree,它本身没有原生CDATA支持,需要自己手动拼接字符串实现,不推荐这么做。
内容的提问来源于stack exchange,提问作者Arthur Zangiev
相关产品推荐
相关产品推荐

