mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 00:43:37 +00:00
142 lines
4 KiB
Python
142 lines
4 KiB
Python
|
try:
|
||
|
from lxml import ElementTree
|
||
|
except ImportError:
|
||
|
try:
|
||
|
import xml.etree.cElementTree as ElementTree
|
||
|
except ImportError:
|
||
|
import xml.etree.ElementTree as ElementTree
|
||
|
|
||
|
|
||
|
class XmlDictObject(dict):
|
||
|
"""
|
||
|
Adds object like functionality to the standard dictionary.
|
||
|
"""
|
||
|
|
||
|
def __init__(self, initdict=None):
|
||
|
if initdict is None:
|
||
|
initdict = {}
|
||
|
dict.__init__(self, initdict)
|
||
|
|
||
|
def __getattr__(self, item):
|
||
|
return self.__getitem__(item)
|
||
|
|
||
|
def __setattr__(self, item, value):
|
||
|
self.__setitem__(item, value)
|
||
|
|
||
|
def __str__(self):
|
||
|
if self.has_key('_text'):
|
||
|
return self.__getitem__('_text')
|
||
|
else:
|
||
|
return ''
|
||
|
|
||
|
@staticmethod
|
||
|
def Wrap(x):
|
||
|
"""
|
||
|
Static method to wrap a dictionary recursively as an XmlDictObject
|
||
|
"""
|
||
|
|
||
|
if isinstance(x, dict):
|
||
|
return XmlDictObject((k, XmlDictObject.Wrap(v)) for (k, v) in x.iteritems())
|
||
|
elif isinstance(x, list):
|
||
|
return [XmlDictObject.Wrap(v) for v in x]
|
||
|
else:
|
||
|
return x
|
||
|
|
||
|
@staticmethod
|
||
|
def _UnWrap(x):
|
||
|
if isinstance(x, dict):
|
||
|
return dict((k, XmlDictObject._UnWrap(v)) for (k, v) in x.iteritems())
|
||
|
elif isinstance(x, list):
|
||
|
return [XmlDictObject._UnWrap(v) for v in x]
|
||
|
else:
|
||
|
return x
|
||
|
|
||
|
def UnWrap(self):
|
||
|
"""
|
||
|
Recursively converts an XmlDictObject to a standard dictionary and returns the result.
|
||
|
"""
|
||
|
|
||
|
return XmlDictObject._UnWrap(self)
|
||
|
|
||
|
|
||
|
def _ConvertDictToXmlRecurse(parent, dictitem):
|
||
|
assert type(dictitem) is not type([])
|
||
|
|
||
|
if isinstance(dictitem, dict):
|
||
|
for (tag, child) in dictitem.iteritems():
|
||
|
if str(tag) == '_text':
|
||
|
parent.text = str(child)
|
||
|
elif type(child) is type([]):
|
||
|
# iterate through the array and convert
|
||
|
for listchild in child:
|
||
|
elem = ElementTree.Element(tag)
|
||
|
parent.append(elem)
|
||
|
_ConvertDictToXmlRecurse(elem, listchild)
|
||
|
else:
|
||
|
elem = ElementTree.Element(tag)
|
||
|
parent.append(elem)
|
||
|
_ConvertDictToXmlRecurse(elem, child)
|
||
|
else:
|
||
|
parent.text = str(dictitem)
|
||
|
|
||
|
|
||
|
def ConvertDictToXml(xmldict):
|
||
|
"""
|
||
|
Converts a dictionary to an XML ElementTree Element
|
||
|
"""
|
||
|
|
||
|
roottag = xmldict.keys()[0]
|
||
|
root = ElementTree.Element(roottag)
|
||
|
_ConvertDictToXmlRecurse(root, xmldict[roottag])
|
||
|
return root
|
||
|
|
||
|
|
||
|
def _ConvertXmlToDictRecurse(node, dictclass):
|
||
|
nodedict = dictclass()
|
||
|
|
||
|
if len(node.items()) > 0:
|
||
|
# if we have attributes, set them
|
||
|
nodedict.update(dict(node.items()))
|
||
|
|
||
|
for child in node:
|
||
|
# recursively add the element's children
|
||
|
newitem = _ConvertXmlToDictRecurse(child, dictclass)
|
||
|
if nodedict.has_key(child.tag):
|
||
|
# found duplicate tag, force a list
|
||
|
if type(nodedict[child.tag]) is type([]):
|
||
|
# append to existing list
|
||
|
nodedict[child.tag].append(newitem)
|
||
|
else:
|
||
|
# convert to list
|
||
|
nodedict[child.tag] = [nodedict[child.tag], newitem]
|
||
|
else:
|
||
|
# only one, directly set the dictionary
|
||
|
nodedict[child.tag] = newitem
|
||
|
|
||
|
if node.text is None:
|
||
|
text = ''
|
||
|
else:
|
||
|
text = node.text.strip()
|
||
|
|
||
|
if len(nodedict) > 0:
|
||
|
# if we have a dictionary add the text as a dictionary value (if there is any)
|
||
|
if len(text) > 0:
|
||
|
nodedict['_text'] = text
|
||
|
else:
|
||
|
# if we don't have child nodes or attributes, just set the text
|
||
|
nodedict = text
|
||
|
|
||
|
return nodedict
|
||
|
|
||
|
def ConvertXmlToDict(root, dictclass=XmlDictObject):
|
||
|
"""
|
||
|
Converts an XML String to a dictionary
|
||
|
"""
|
||
|
|
||
|
if isinstance(root, basestring):
|
||
|
root = ElementTree.fromstring(root)
|
||
|
elif not isinstance(root, ElementTree.Element):
|
||
|
raise TypeError, 'Expected string'
|
||
|
|
||
|
return dictclass({root.tag: _ConvertXmlToDictRecurse(root, dictclass)})
|