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

Python Cheetah3遍历单元素集合时行为异常问题咨询

XML集合单元素解析异常问题

问题现象

解析XML集合时,集合元素数量大于1时代码正常运行,仅含1个元素时行为异常。

XML输入

<?xml version="1.0" encoding="UTF-8"?>
<example code="HI">
    <collection1>
        <item>
            <name>item1</name>
        </item>
        <item>
            <name>item2</name>
        </item>
    </collection1>
    <collection2>
        <item>
            <name>item3</name>
        </item>
    </collection2>
</example>

Python代码

#!/usr/bin/env python

import xmltodict
from Cheetah.Template import Template


with open('example.xml', 'r') as f:
    example_xml = f.read()
example_dict = xmltodict.parse(example_xml)

templateDefinition = "Collection 1:\n" \
                     "#for $item in $example.collection1.item\n" \
                     "$item\n" \
                     "#end for\n" \
                     "Collection 2:\n" \
                     "#for $item in $example.collection2.item\n" \
                     "$item\n" \
                     "#end for\n"
template = Template(templateDefinition, searchList=[example_dict])
print(str(template))

运行输出

Collection 1:
{'name': 'item1'}
{'name': 'item2'}
Collection 2:
name

collection2未返回预期的{'name': 'item3'},而是输出了name。

原因分析

这是xmltodict库的默认行为导致的:

  • 当XML节点包含多个同名子元素(如collection1下的多个<item>)时,xmltodict.parse会将其解析为列表,因此collection1.item是一个包含两个字典的列表,Cheetah的#for循环可以正常遍历每个元素。
  • 当XML节点仅包含一个同名子元素(如collection2下的单个<item>)时,xmltodict.parse会直接将其解析为字典对象,而非列表。此时collection2.item就是{'name': 'item3'}这个字典,Cheetah的#for循环遍历字典时,默认会遍历字典的键,因此输出了键名name。

解决方案

在调用xmltodict.parse时,使用force_list参数强制指定需要始终解析为列表的节点名称,确保无论该节点下有多少个子元素,都统一以列表形式返回。

修改后的代码如下:

#!/usr/bin/env python

import xmltodict
from Cheetah.Template import Template


with open('example.xml', 'r') as f:
    example_xml = f.read()
# 指定item节点强制转为列表
example_dict = xmltodict.parse(example_xml, force_list=['item'])

templateDefinition = "Collection 1:\n" \
                     "#for $item in $example.collection1.item\n" \
                     "$item\n" \
                     "#end for\n" \
                     "Collection 2:\n" \
                     "#for $item in $example.collection2.item\n" \
                     "$item\n" \
                     "#end for\n"
template = Template(templateDefinition, searchList=[example_dict])
print(str(template))

修改后运行输出

Collection 1:
{'name': 'item1'}
{'name': 'item2'}
Collection 2:
{'name': 'item3'}

此时collection2的解析结果符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:04:57