Skip to content

Instantly share code, notes, and snippets.

@w495
Created October 10, 2016 16:42
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 w495/d9134a65f7eb0b2d543e58ba4dc3288b to your computer and use it in GitHub Desktop.
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
# -*- 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