Last active
August 29, 2015 13:57
-
-
Save JobsDong/9542365 to your computer and use it in GitHub Desktop.
dict to xml and xml to dict
This file contains hidden or 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
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