Skip to content

Instantly share code, notes, and snippets.

@Deiru2k
Last active November 23, 2015 14:42
Show Gist options
  • Save Deiru2k/a0e436dd8f88a0da08c1 to your computer and use it in GitHub Desktop.
Save Deiru2k/a0e436dd8f88a0da08c1 to your computer and use it in GitHub Desktop.
Dict To Xml
from xml.etree import ElementTree as et
from xml.dom import minidom
"""
Convert Python dict to XML using a special set of rules
Function build_xml takes a specialy formatted dict and returns xml.etree.ElementTree Element.
1) There can be only one Root Element, it must be at a top-level of a dictionary and it should be the only element at
top-level
2) Keys are element names, key values should be dicts with element params.
3) If there should be more than one elements with the same name, key value could be a list of dicts with params.
4) If element should have children, they must be defined within "children" param
5) Attributes should be a dict containing a list of attributes of element, where key is attribute name and it's value
is attribute's value
Example of a dict that complies to such rules:
my_xml = {
"root": {
"children": {
"child": {
"attributes": {"myAttr1": "1", "myAttr2": "dogeshibe"},
"content": "Wow, such content, very within element, much tags",
"children": {
"doge": [
{"content": "Doge 1"},
{"content": "Doge 2"}
]
}
}
}
}
}
This should convert into:
<root>
<child myAttr1="1" myAttr2="dogeshibe">
Wow, such content, very within element, much tags
<doge>Doge 1</doge>
<doge>Doge 2</doge>
</child>
</root>
You can try to construct your dict and convert to XML
You can use prettify function to make a pretty, tab-formatted string from your Element.
@Misaka42, 2015
Do whatever the fuck you want.
"""
def build_xml(d):
"""
Builds XML from dict
"""
root_key = d.keys()[0]
root = d[root_key]
root_element = et.Element(root_key)
if 'content' in root: root_element.text = root['content']
if 'attributes' in root: root_element.attrib = root['attributes']
result = process_tree(root['children'], root_element)
return result
def process_tree(tree, root_element):
def process_node(key, node):
element = et.Element(key)
if 'content' in node:
element.text = node['content']
if 'attributes' in node: element.attrib = node['attributes']
if 'children' in node:
element = process_tree(node['children'], element)
root_element.append(element)
for key in tree:
node = tree[key]
if isinstance(node, dict):
process_node(key, node)
elif isinstance(node, list):
for n in node: process_node(key, n)
return root_element
def prettify(elem):
"""Return a pretty-printed XML string for the Element.
"""
rough_string = et.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" " * 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment