How to read a xml file in python as dictionary?

Viewed 42

There has been some answers like here, here and here, but they do not seem to work for me to open an xml file and get the contents as a simple and convenient python dict.

Here is what I tried:

from collections import defaultdict

def etree_to_dict(t):
    d = {t.tag: {} if t.attrib else None}
    children = list(t)
    if children:
        dd = defaultdict(list)
        for dc in map(etree_to_dict, children):
            for k, v in dc.items():
                dd[k].append(v)
        d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.items()}}
    if t.attrib:
        d[t.tag].update(('@' + k, v) for k, v in t.attrib.items())
    if t.text:
        text = t.text.strip()
        if children or t.attrib:
            if text:
              d[t.tag]['#text'] = text
        else:
            d[t.tag] = text
    return d

with open('run.tcx', 'r') as f:
    data = f.read()

from pprint import pprint
pprint(etree_to_dict(data))

which resulted in a error

Traceback (most recent call last):
  File "tester.py", line 33, in <module>
    pprint(etree_to_dict(data))
  File "tester.py", line 8, in etree_to_dict
    d = {t.tag: {} if t.attrib else None}
AttributeError: 'str' object has no attribute 'tag'

I also tried with some other function from this answer:

import xml.etree.ElementTree as ET

from copy import copy

    def dictify(r,root=True):
        if root:
            return {r.tag : dictify(r, False)}
        d=copy(r.attrib)
        if r.text:
            d["_text"]=r.text
        for x in r.findall("./*"):
            if x.tag not in d:
                d[x.tag]=[]
            d[x.tag].append(dictify(x,False))
        return d

and got the same error. The file I am opening starts as follows

<?xml version="1.0" encoding="UTF-8"?><TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-i
nstance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd"><Activities><Activity S
port="Running"><Id>2022-08-20T05:58:57Z</Id><Lap StartTime="2022-08-20T05:58:57Z"><Calories>1060.0</Calories><DistanceMeters>14468.162</DistanceMeters><TotalTimeSeconds>6259.
0</TotalTimeSeconds><Track><Trackpoint>...

and seems to be in xml format.

Am I doing something fundamentally wrong here?

0 Answers
Related