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
相关产品推荐
相关产品推荐

