import xml.dom.minidom import base64 import string def parse(fname): """This is the main interface.""" doc = xml.dom.minidom.parse(fname) assert doc.documentElement.tagName == 'plist' return handle(doc.documentElement) def handle(elem): assert (elem.nodeType == elem.ELEMENT_NODE) if elem.tagName == 'dict': return dict(elem) elif elem.tagName == 'string': return string(elem) elif elem.tagName == 'array': return array(elem) elif elem.tagName == 'integer': return integer(elem) elif elem.tagName == 'data': return data(elem) elif elem.tagName == 'plist': return array(elem) # unhandled tag return None def integer(elem): try: i = int(elem.firstChild.data) except ValueError: i = None def string(elem): try: d = elem.firstChild.data except AttributeError: d = '' return d def data(elem): try: d = base64.decodestring(elem.firstChild.data) except: d = elem.firstChild.data return d def key(elem): return elem.firstChild.data def array(elem): l = [] for sub in filter(f, elem.childNodes): l.append(handle(sub)) return l def dict(elem): d = {} l = filter(f, elem.childNodes) i = 0 while i < len(l): if l[i].tagName == 'key': d[key(l[i])] = handle(l[i+1]) i = i + 2 return d def f(n): "filter to get rid of non-element nodes" if n.nodeType == n.ELEMENT_NODE: return n return None