如何用Python及lxml创建含多命名空间的墨西哥CFDI XML结构?
使用Python和lxml创建墨西哥CFDI发票XML结构
首先确保已安装lxml库:
pip install lxml
以下是生成目标XML结构的完整代码:
from lxml import etree # 定义CFDI相关命名空间映射 NS_MAP = { 'cfdi': 'http://www.sat.gob.mx/cfd/4', 'cce11': 'http://www.sat.gob.mx/ComercioExterior11', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance' } # 创建根节点 <cfdi:Comprobante> root = etree.Element( '{http://www.sat.gob.mx/cfd/4}Comprobante', nsmap=NS_MAP ) # 设置根节点属性 root.set('Version', '4.0') root.set('Fecha', '2023-12-27T11:53:50') root.set( '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation', 'http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/ComercioExterior11 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd' ) # 添加<cfdi:Emisor>节点 etree.SubElement( root, '{http://www.sat.gob.mx/cfd/4}Emisor', Rfc='XAXX010101XXX', Nombre='COMPANY', RegimenFiscal='601' ) # 添加<cfdi:Receptor>节点 etree.SubElement( root, '{http://www.sat.gob.mx/cfd/4}Receptor', Rfc='XEXX010101XXX', Nombre='COMPANY', DomicilioFiscalReceptor='00000', RegimenFiscalReceptor='601', UsoCFDI='G01' ) # 添加<cfdi:Conceptos>及子节点 conceptos = etree.SubElement(root, '{http://www.sat.gob.mx/cfd/4}Conceptos') concepto = etree.SubElement( conceptos, '{http://www.sat.gob.mx/cfd/4}Concepto', ClaveProdServ='00000000', NoIdentificacion='XXXXX', Cantidad='1.000000', ClaveUnidad='EA', Unidad='PIEZA', Descripcion='XXXXX', ValorUnitario='1.00', Importe='1.00', ObjetoImp='00' ) # 添加Concepto下的Impuestos节点 concepto_impuestos = etree.SubElement(concepto, '{http://www.sat.gob.mx/cfd/4}Impuestos') concepto_traslados = etree.SubElement(concepto_impuestos, '{http://www.sat.gob.mx/cfd/4}Traslados') etree.SubElement( concepto_traslados, '{http://www.sat.gob.mx/cfd/4}Traslado', Base='1.00', Importe='1.00', Impuesto='000', TipoFactor='Tasa', TasaOCuota='0.000000' ) # 添加<cfdi:Impuestos>及子节点 impuestos = etree.SubElement( root, '{http://www.sat.gob.mx/cfd/4}Impuestos', TotalImpuestosTrasladados='1.00' ) traslados = etree.SubElement(impuestos, '{http://www.sat.gob.mx/cfd/4}Traslados') # 添加第一个Traslado etree.SubElement( traslados, '{http://www.sat.gob.mx/cfd/4}Traslado', Base='1.00', Importe='1.00', Impuesto='000', TipoFactor='Tasa', TasaOCuota='0.000000' ) # 添加第二个Traslado etree.SubElement( traslados, '{http://www.sat.gob.mx/cfd/4}Traslado', Base='1.00', Importe='1.00', Impuesto='000', TipoFactor='Tasa', TasaOCuota='0.000000' ) # 生成格式化XML并输出 xml_str = etree.tostring(root, encoding='utf-8', pretty_print=True, xml_declaration=True) print(xml_str.decode('utf-8'))
关键说明
- 命名空间处理:lxml创建带命名空间的元素时,需用
{命名空间URI}元素名格式,通过nsmap参数定义前缀与URI的映射关系。 - 属性设置:普通属性直接用
set()方法,带命名空间的属性(如xsi:schemaLocation)需使用完整命名空间URI前缀。 - 节点层级:通过
etree.SubElement()逐层创建子节点,严格对应目标XML的层级结构。 - 输出控制:
pretty_print=True生成缩进格式化的XML,xml_declaration=True自动添加XML声明头。
内容的提问来源于stack exchange,提问作者Hugo
相关产品推荐
相关产品推荐

