Source code for spyne.util.etreeconv
#
# spyne - Copyright (C) Spyne contributors.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
"""This module contains the utility methods that convert an ElementTree
hierarchy to python dicts and vice versa.
"""
from lxml import etree
from spyne.util.odict import odict
def root_dict_to_etree(d):
[docs] """Converts a dictionary to an xml hiearchy. Just like a valid xml document,
the dictionary must have a single element. The format of the child
dictionaries is the same as :func:`dict_to_etree`.
"""
assert len(d) == 1
key, = d.keys()
retval = etree.Element(key)
for val in d.values():
break
if isinstance(val, dict) or isinstance(val, odict):
dict_to_etree(val, retval)
else:
for a in val:
dict_to_etree(a, retval)
return retval
def dict_to_etree(d, parent):
[docs] """Takes a the dict whose value is either None or an instance of dict, odict
or an iterable. The iterables can contain either other dicts/odicts or
str/unicode instances.
"""
for k, v in d.items():
if v is None or len(v) == 0:
etree.SubElement(parent, k)
elif isinstance(v, dict) or isinstance(v, odict):
child = etree.SubElement(parent, k)
dict_to_etree(v, child)
else:
for e in v:
child=etree.SubElement(parent, k)
if isinstance(e, dict) or isinstance(e, odict):
dict_to_etree(e, child)
else:
child.text=str(e)
def root_etree_to_dict(element, iterable=(list, list.append)):
[docs] """Takes an xml root element and returns the corresponding dict. The second
argument is a pair of iterable type and the function used to add elements to
the iterable. The xml attributes are ignored.
"""
return {element.tag: iterable[0]([etree_to_dict(element, iterable)])}
def etree_to_dict(element, iterable=(list, list.append)):
[docs] """Takes an xml root element and returns the corresponding dict. The second
argument is a pair of iterable type and the function used to add elements to
the iterable. The xml attributes are ignored.
"""
if (element.text is None) or element.text.isspace():
retval = odict()
for elt in element:
if not (elt.tag in retval):
retval[elt.tag] = iterable[0]()
iterable[1](retval[elt.tag], etree_to_dict(elt, iterable))
else:
retval = element.text
return retval
def etree_strip_namespaces(element):
[docs] """Removes any namespace information form the given element recursively."""
retval = etree.Element(element.tag.rpartition('}')[-1])
retval.text = element.text
for a in element.attrib:
retval.attrib[a.rpartition('}')[-1]] = element.attrib[a]
for e in element:
retval.append(etree_strip_namespaces(e))
return retval