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

Odoo添加XML附件报错:b2a_base64()参数应为字符串或缓冲区而非列表

解决Odoo创建XML附件时的TypeError问题

这个问题我之前处理过,核心原因有两个:一是你生成的root是列表类型,不符合base64编码函数的参数要求;二是对lxml.etree.tostring()的返回值以及Odooir.attachment字段的格式要求理解有偏差。下面一步步给你解决:

1. 为什么root会是列表?

正常情况下,lxml.etree.tostring()接收单个XML节点,返回的是字节串(bytes),而不是列表。你得到列表,大概率是因为传入的xml变量本身是一个节点列表(比如用xpath查询返回的结果),而不是单个XML根节点。

所以第一步要先把列表转成单个节点:

# 先确认xml的类型,如果是列表就取第一个有效节点
if isinstance(xml, list) and xml:
    xml_root_node = xml[0]
else:
    xml_root_node = xml  # 如果已经是单个节点就直接用

2. 正确生成XML字节串并编码

接下来用tostring()生成标准的XML字节串,建议指定编码和XML声明(避免乱码问题):

from lxml import etree
import base64

# 生成带编码声明的XML字节串
xml_bytes = etree.tostring(xml_root_node, encoding='utf-8', xml_declaration=True)

注意:Python3中base64.encodestring()已经被标记为过时,官方推荐用base64.b64encode(),它接收bytes类型,返回也是bytes类型,最后我们需要把它转成字符串(因为Odoo的datas字段要求是base64编码的字符串)。

3. 修正Odoo附件创建代码

把上面的步骤整合后,最终的创建附件代码应该是这样的:

# 先处理XML节点
if isinstance(xml, list) and xml:
    xml_root_node = xml[0]
else:
    xml_root_node = xml

# 生成XML字节串
xml_bytes = etree.tostring(xml_root_node, encoding='utf-8', xml_declaration=True)

# 创建附件
self.env['ir.attachment'].create({ 
    'name': 'NFe_Autorizada.xml', 
    'type': 'binary', 
    'datas': base64.b64encode(xml_bytes).decode('utf-8'),  # 编码后转成字符串
    'datas_fname': 'NFe_Autorizada.xml', 
    'res_model': 'invoice.eletronic', 
    'res_id': self.id, 
    'mimetype': 'application/xml'
})

为什么之前用str(root)不行?

如果root是列表,str(root)会把列表转成类似[b'<xml>...</xml>']的字符串,里面包含了列表的括号和b''前缀,这不是纯XML内容,编码后肯定不符合要求。必须先把列表转成单个节点,再生成正确的XML字节串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:12:38