Skip to content

Instantly share code, notes, and snippets.

@superboum
Created January 13, 2022 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superboum/ee5f28c748e4114550a72313abe267f2 to your computer and use it in GitHub Desktop.
Save superboum/ee5f28c748e4114550a72313abe267f2 to your computer and use it in GitHub Desktop.
Convert Keeweb XML output to KeepassXC CSV
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment