Created
October 10, 2016 16:42
-
-
Save w495/d9134a65f7eb0b2d543e58ba4dc3288b to your computer and use it in GitHub Desktop.
Dumps python dict to xml string. Current example is suitable for dumping OVS-XML format from python dictionay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import absolute_import, division, print_function | |
import lxml.etree as et | |
import six | |
def dumps(data): | |
name = data.keys()[0] | |
value = data[name] | |
return data2xml_(value, name=name) | |
def get_ns(name, nsmap, delim=':'): | |
nlist = name.split(delim) | |
if len(nlist) > 1: | |
ns_name = nlist[0] | |
ns = nsmap.get(ns_name) | |
return dict( | |
ns=ns, | |
name=nlist[1] | |
) | |
return dict( | |
ns=None, | |
name=nlist[0] | |
) | |
def get_name(name, nsmap): | |
ns_dict = get_ns(name, nsmap) | |
if not ns_dict['ns']: | |
fmt = "{name}" | |
else: | |
fmt = "{{{ns}}}{name}" | |
return fmt.format(**ns_dict) | |
def data2xml_(data, name='video'): | |
ovs_schema = 'http://webmaster.yandex.ru/schemas/video' | |
sm_schema = 'http://webmaster.yandex.ru/schemas/video' | |
xsi = "http://www.w3.org/2001/XMLSchema-instance" | |
xmlns = ovs_schema | |
schemaLocation = ovs_schema | |
nsmap = { | |
None: sm_schema, | |
'ovs': ovs_schema | |
} | |
root = et.Element( | |
get_name(name, nsmap), | |
nsmap=nsmap, | |
attrib={ | |
"{{{xsi}}}schemaLocation".format(xsi=xsi): schemaLocation | |
} | |
) | |
data = et.tostring( | |
buildxml( | |
root, | |
data, | |
xmlns=xmlns, | |
nsmap=nsmap, | |
), | |
xml_declaration=True, | |
encoding="UTF-8", | |
pretty_print=True | |
) | |
result = "{data}".format( | |
data=data | |
) | |
return result | |
def buildxml(root, data, xmlns=None, nsmap=None): | |
if isinstance(data, dict): | |
__data__ = data.get('__data__') | |
if __data__: | |
buildxml(root, __data__, xmlns, nsmap) | |
else: | |
__list__ = data.get('__list__') | |
if __list__: | |
for item in __list__: | |
buildxml(root, item, xmlns, nsmap) | |
else: | |
for name, value in six.iteritems(data): | |
attrib = None | |
if isinstance(value, dict): | |
attrib = value.pop('__attr__', dict()) | |
for ak, av in six.iteritems(attrib): | |
attrib[ak] = str(av) | |
sub_element = et.SubElement( | |
root, | |
get_name(name, nsmap), | |
attrib=attrib | |
) | |
buildxml(sub_element, value, xmlns, nsmap) | |
elif isinstance(data, tuple) or isinstance(data, list): | |
for value in data: | |
if not isinstance(value, dict): | |
value = dict(item=value) | |
buildxml(root, value, xmlns, nsmap) | |
elif isinstance(data, basestring): | |
root.text = data | |
else: | |
root.text = str(data) | |
return root | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment