Variable Changes in Recursive Backtracking
def parse_xml_to_dict(self, xml):
if len(xml) == 0: # reached the bottom level, return the info for this tag directly
return {xml.tag: xml.text}
result = {}
print("bbb")
for child in xml:
print("aaa")
child_result = parse_xml_to_dict(child) # recursively traverse the tag info
print(result)
# if child.tag != 'object':
result[child.tag] = child_result[child.tag]
print(result)
# else:
# if child.tag not in result: # there may be multiple objects, so they need to go into a list
# result[child.tag] = []
# result[child.tag].append(child_result[child.tag])
return {xml.tag: result}
Input data:
<annotation>
<folder>VOC2007</folder>
<filename>000001.jpg</filename>
<source>
<database>The VOC2007 Database</database>
<annotation>PASCAL VOC2007</annotation>
<image>flickr</image>
<flickrid>341012865</flickrid>
</source>
<owner>
<flickrid>Fried Camels</flickrid>
<name>Jinky the Fruit Bat</name>
</owner>
<size>
<width>353</width>
<height>500</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>dog</name>
<pose>Left</pose>
<truncated>1</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>48</xmin>
<ymin>240</ymin>
<xmax>195</xmax>
<ymax>371</ymax>
</bndbox>
</object>
<object>
<name>person</name>
<pose>Left</pose>
<truncated>1</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>8</xmin>
<ymin>12</ymin>
<xmax>352</xmax>
<ymax>498</ymax>
</bndbox>
</object>
</annotation>
Output:
bbb
aaa
{}
{'folder': 'VOC2007'}
aaa
{'folder': 'VOC2007'}
{'folder': 'VOC2007', 'filename': '000001.jpg'}
aaa
bbb
aaa
{}
{'database': 'The VOC2007 Database'}
aaa
{'database': 'The VOC2007 Database'}
{'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007'}
aaa
{'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007'}
{'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr'}
aaa
{'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr'}
{'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}
{'folder': 'VOC2007', 'filename': '000001.jpg'}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}}
aaa
bbb
aaa
{}
{'flickrid': 'Fried Camels'}
aaa
{'flickrid': 'Fried Camels'}
{'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}}
aaa
bbb
aaa
{}
{'width': '353'}
aaa
{'width': '353'}
{'width': '353', 'height': '500'}
aaa
{'width': '353', 'height': '500'}
{'width': '353', 'height': '500', 'depth': '3'}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}}
aaa
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0'}
aaa
bbb
aaa
{}
{'name': 'dog'}
aaa
{'name': 'dog'}
{'name': 'dog', 'pose': 'Left'}
aaa
{'name': 'dog', 'pose': 'Left'}
{'name': 'dog', 'pose': 'Left', 'truncated': '1'}
aaa
{'name': 'dog', 'pose': 'Left', 'truncated': '1'}
{'name': 'dog', 'pose': 'Left', 'truncated': '1', 'difficult': '0'}
aaa
bbb
aaa
{}
{'xmin': '48'}
aaa
{'xmin': '48'}
{'xmin': '48', 'ymin': '240'}
aaa
{'xmin': '48', 'ymin': '240'}
{'xmin': '48', 'ymin': '240', 'xmax': '195'}
aaa
{'xmin': '48', 'ymin': '240', 'xmax': '195'}
{'xmin': '48', 'ymin': '240', 'xmax': '195', 'ymax': '371'}
{'name': 'dog', 'pose': 'Left', 'truncated': '1', 'difficult': '0'}
{'name': 'dog', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '48', 'ymin': '240', 'xmax': '195', 'ymax': '371'}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0'}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0', 'object': {'name': 'dog', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '48', 'ymin': '240', 'xmax': '195', 'ymax': '371'}}}
aaa
bbb
aaa
{}
{'name': 'person'}
aaa
{'name': 'person'}
{'name': 'person', 'pose': 'Left'}
aaa
{'name': 'person', 'pose': 'Left'}
{'name': 'person', 'pose': 'Left', 'truncated': '1'}
aaa
{'name': 'person', 'pose': 'Left', 'truncated': '1'}
{'name': 'person', 'pose': 'Left', 'truncated': '1', 'difficult': '0'}
aaa
bbb
aaa
{}
{'xmin': '8'}
aaa
{'xmin': '8'}
{'xmin': '8', 'ymin': '12'}
aaa
{'xmin': '8', 'ymin': '12'}
{'xmin': '8', 'ymin': '12', 'xmax': '352'}
aaa
{'xmin': '8', 'ymin': '12', 'xmax': '352'}
{'xmin': '8', 'ymin': '12', 'xmax': '352', 'ymax': '498'}
{'name': 'person', 'pose': 'Left', 'truncated': '1', 'difficult': '0'}
{'name': 'person', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '8', 'ymin': '12', 'xmax': '352', 'ymax': '498'}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0', 'object': {'name': 'dog', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '48', 'ymin': '240', 'xmax': '195', 'ymax': '371'}}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0', 'object': {'name': 'person', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '8', 'ymin': '12', 'xmax': '352', 'ymax': '498'}}}
{'folder': 'VOC2007', 'filename': '000001.jpg', 'source': {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr', 'flickrid': '341012865'}, 'owner': {'flickrid': 'Fried Camels', 'name': 'Jinky the Fruit Bat'}, 'size': {'width': '353', 'height': '500', 'depth': '3'}, 'segmented': '0', 'object': {'name': 'person', 'pose': 'Left', 'truncated': '1', 'difficult': '0', 'bndbox': {'xmin': '8', 'ymin': '12', 'xmax': '352', 'ymax': '498'}}}
Note: the for loop traverses nodes on the same level, e.g. here: <folder>, <filename>, <source>, <owner>, etc.
After
<folder>has been traversed, it has no child nodes, so we backtrack. Note that we backtrack to the point inside the for loop (where print(“aaa”) is), and result now holds the value after<folder>was traversed, because result is defined outside the for loop. The same applies to<filename>.When we reach
<source>, it has children, so the function is called recursively and result starts out empty. Once that for loop finishes, *there is a return that passes result back to where<source>was entered, i.e. the children's result is returned as the value for the parent node<source>.child_result = parse_xml_to_dict(child) # recursively traverse the tag info
child_result stores the children's result, while result reverts to the parent node's result.