Skip to content

Instantly share code, notes, and snippets.

@JobsDong
Last active August 29, 2015 13:57
Show Gist options
  • Save JobsDong/9542365 to your computer and use it in GitHub Desktop.
Save JobsDong/9542365 to your computer and use it in GitHub Desktop.
dict to xml and xml to dict
from xml.dom import minidom
from collections import Mapping
from petl.io import RowContainer
from lxml import etree
def fromxml(source, rowmatch, *args, **kwargs):
return XmlView(source, rowmatch, *args, **kwargs)
class XmlView(RowContainer):
def __init__(self, source, rowmatch, *args, **kwargs):
self.source = source
self.args = args
self.rmatch = rowmatch
def __iter__(self):
context = etree.iterparse(self.source, events=('start','end'))
_stack = []
_data = ''
for event, elem in context:
tag = elem.tag
if event == "start":
_stack.append([elem.tag])
#_data = elem.text
elif event == "end":
_data = elem.text
last_tag = _stack.pop()
if len(last_tag) == 1: #leaf
data = _data
else:
if tag not in self.rmatch:
# build a dict, repeating pairs get pushed into lists
data = {}
for k, v in last_tag[1:]:
if k not in data:
data[k] = v
else:
el = data[k]
if type(el) is not list:
data[k] = [el, v]
else:
el.append(v)
else: #force into a list
res = dict(last_tag[1:])
#res = {k:v for k, v in last_tag[1:]}
#res = [{k:v} for k, v in last_tag[1:]]
yield res
#yield {tag:res}
data = ''
if _stack:
_stack[-1].append((tag, data))
else:
result = {tag:data}
_data = ''
elem.clear()
def dict2xml(structure, tostring=False):
"""将字典转换成xml的函数
Args:
structure: dict, 字典
tostring: boolean, 是否输出未string, 或者doc
"""
impl = minidom.getDOMImplementation()
doc = impl.createDocument(None, 'shop', None)
dict2element(doc.documentElement, structure, doc)
return doc.documentElement.toxml() if tostring else doc
def dict2element(root, structure, doc):
"""
Gets a dictionary like structure and converts its
content into xml elements. After that appends
resulted elements to root element. If root element
is a string object creates a new elements with the
given string and use that element as root.
This function returns a xml element object.
"""
assert isinstance(structure, Mapping), 'Structure must be a mapping object such as dict'
# if root is a string make it a element
if isinstance(root, str):
root = doc.createElement(root)
for key, value in structure.iteritems():
if isinstance(value, Mapping):
el = doc.createElement(str(key))
dict2element(el, value, doc)
root.appendChild(el)
elif isinstance(value, list):
for l in value:
el = doc.createElement(str(key))
dict2element(el, l, doc)
root.appendChild(el)
else:
el = doc.createElement(str(key))
if not value:
txt = ''
elif isinstance(value, unicode):
txt = value.encode('utf8')
else:
txt = value
el.appendChild(doc.createTextNode(txt))
root.appendChild(el)
return root
if __name__ == "__mian__":
print dict2xml({"hell": 3, "world": "nimei"}, True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment