如何在Python中根据用户输入条目数复制XML父标签及子标签
Python实现XML中InvoiceLine标签的批量复制与内容修改
核心实现思路
- 借助
lxml库解析带命名空间的XML,处理cac:、cbc:前缀的节点 - 提取原始
<cac:InvoiceLine>作为模板,批量复制生成指定数量的节点 - 针对每个复制后的节点,修改
<cac:Item>下的子标签内容(如Name、Percent) - 替换根节点下的原始模板节点,添加所有生成的新节点后格式化输出
具体代码实现
首先安装依赖库:
pip install lxml
完整代码示例:
from lxml import etree # 原始XML内容(也可从文件读取,替换为etree.parse('input.xml').getroot()) original_xml = """<Invoice> <cac:InvoiceLine> <cac:Item> <cbc:Name>Item A</cbc:Name> <cbc:Percent>20</cbc:Percent> <cbc:ID>VAT</cbc:ID> </cac:Item> </cac:InvoiceLine> </Invoice>""" # 命名空间映射(需与原始XML中的xmlns定义一致,示例为UBL标准命名空间) ns_map = { 'cac': 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2', 'cbc': 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' } # 解析XML root = etree.fromstring(original_xml.encode('utf-8')) # 获取模板节点并移除(后续添加新生成的节点) template_line = root.find('.//cac:InvoiceLine', namespaces=ns_map) root.remove(template_line) # 获取用户输入的条目数量 entry_count = int(input("请输入条目数量:")) # 批量生成节点 for idx in range(entry_count): # 深拷贝模板节点,避免修改模板影响后续复制 new_line = etree.ElementTree(template_line).getroot() # 修改<cbc:Name>内容 name_node = new_line.find('.//cbc:Name', namespaces=ns_map) name_node.text = f"Item {chr(ord('A') + idx)}" # 修改<cbc:Percent>内容(示例为递增数值,可改为用户输入或自定义逻辑) percent_node = new_line.find('.//cbc:Percent', namespaces=ns_map) percent_node.text = str(20 + 30 * idx) # 将新节点添加到根节点 root.append(new_line) # 格式化输出XML output_xml = etree.tostring( root, encoding='utf-8', pretty_print=True, xml_declaration=False ).decode('utf-8') print(output_xml)
关键注意事项
- 命名空间正确性:必须确保
ns_map中的URL与原始XML的xmlns:cac、xmlns:cbc属性值完全一致,否则无法定位节点。 - 节点拷贝方式:使用
etree.ElementTree(template_line).getroot()实现深拷贝,避免修改模板节点影响后续复制。 - 内容自定义:可修改
name_node.text和percent_node.text的赋值逻辑,比如通过循环获取用户输入的每个条目名称和百分比,而非自动生成。
内容的提问来源于stack exchange,提问作者Starlight
相关产品推荐
相关产品推荐

