2

I'm trying to write some code that will parse a collection/list/array etc and I had this working when the size is greater than 1. However when only 1 item is in the collection the code fails as the behaviour appears to be different. Using the below input

<?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>

and the following code

#!/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))

I get this output

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

Why does collection 2 not return a single item of {'name': 'item3'}?

Cynan
  • 160
  • 1
  • 5

2 Answers2

1

Not a problem in Cheetah at all. Try this:

#!/usr/bin/env python

import xmltodict

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

example = example_dict['example']
items = example['collection2']['item']
print(items)

for item in items:
    print(item)

In short: example['collection1']['item'] is a list of dicts while example['collection2']['item'] is just a dict. The bottom line: verify your data structures.

phd
  • 82,685
  • 13
  • 120
  • 165
0

Maybe a Cheetah bug, I get the same strange result. You can parse the xml directly instead:

import xml.etree.ElementTree as ET

tree = ET.parse("foo.xml")
root = tree.getroot()

for col in root.findall("./"):
    print(col.tag)
    for nam in col.findall("./item/name"):
        print({nam.tag:nam.text})

Output:

collection1
{'name': 'item1'}
{'name': 'item2'}
collection2
{'name': 'item3'}
Hermann12
  • 1,709
  • 2
  • 5
  • 14
  • 1
    Aah I think it's to do wit this actually, xmltodict, and not Cheetah at all. https://github.com/martinblech/xmltodict/issues/14 – Cynan May 11 '23 at 23:18