import xmltodict,collections,csv def group(v, out): if 'Entry' in v: item = v['Entry'] if isinstance(item, collections.OrderedDict): entry(item, out) elif isinstance(item, list): for e in item: entry(e, out) if 'Group' in v: item = v['Group'] if isinstance(item, collections.OrderedDict): group(item, out) elif isinstance(item, list): for g in item: group(g, out) def entry(e, out): title, username, url, password, notes = "", "", "", "", "" if 'String' in e: for s in e['String']: if 'Key' in s and 'Value' in s: key, val = s['Key'], s['Value'] if key == 'UserName': username = val elif key == 'URL': url = val elif key == 'Title': title = val elif key == 'Notes' and val: notes = val.replace('\n', '\\n') elif key == 'Password': if isinstance(val, collections.OrderedDict): password = val['#text'] else: password = val out.writerow([title, username, url, password, notes]) root = None with open('passwords.xml', 'r') as f: pw = xmltodict.parse(f.read()) root = pw['KeePassFile']['Root']['Group'] with open('passwords.csv', 'w', newline='') as csvfile: out = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) out.writerow(["title", "username", "url", "password", "note"]) group(root, out)