diff --git a/CHANGES b/CHANGES
index 39e6725..70d9904 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,7 @@
Changes
=======
+* 0.64: huTools.structured.dict2xml now supports flat lists and unordered content
* 0.63: huTools.cache added
* 0.62: huTools.structured.Struct has a __nonzero__ method
* 0.61: huTools.structured.Struct and make_struct handle lists and get an items() method
diff --git a/huTools/structured.py b/huTools/structured.py
index 145b817..0cc1ddc 100644
--- a/huTools/structured.py
+++ b/huTools/structured.py
@@ -8,7 +8,6 @@
import xml.etree.cElementTree as ET
from StringIO import StringIO
-
# Basic conversation goal here is converting a dict to an object allowing
# more comfortable access. `Struct()` and `make_struct()` are used to archive
# this goal.
@@ -206,20 +205,31 @@ def make_struct(obj, default=None, nodefault=False):
# Code is based on http://code.activestate.com/recipes/573463/
-def _convert_dict_to_xml_recurse(parent, dictitem, listnames):
+def _convert_dict_to_xml_recurse(parent, dictitem, listnames, sort=True):
"""Helper Function for XML conversion."""
- # we can't convert bare lists
- assert not isinstance(dictitem, list)
+
+ if isinstance(dictitem, list):
+ raise TypeError('Unable to convert bare lists')
if isinstance(dictitem, dict):
- for (tag, child) in sorted(dictitem.iteritems()):
+ items = dictitem.iteritems()
+ if sort:
+ items = sorted(items)
+ for (tag, child) in items:
if isinstance(child, list):
# iterate through the array and convert
- listelem = ET.Element(tag)
- parent.append(listelem)
+ itemname = listnames.get(tag, 'item')
+ if itemname is not None:
+ listelem = ET.SubElement(parent, tag)
+ else:
+ listelem = parent
+
for listchild in child:
- elem = ET.Element(listnames.get(tag, 'item'))
- listelem.append(elem)
+ if itemname is not None:
+ elem = ET.SubElement(listelem, itemname)
+ else:
+ elem = ET.SubElement(listelem, tag)
+
_convert_dict_to_xml_recurse(elem, listchild, listnames)
else:
if tag.startswith('@'):
@@ -232,7 +242,7 @@ def _convert_dict_to_xml_recurse(parent, dictitem, listnames):
parent.text = unicode(dictitem)
-def dict2et(xmldict, roottag='data', listnames=None):
+def dict2et(xmldict, roottag='data', listnames=None, sort=True):
"""Converts a dict to an ElementTree.
Converts a dictionary to an XML ElementTree Element::
@@ -242,9 +252,9 @@ def dict2et(xmldict, roottag='data', listnames=None):
>>> ET.tostring(root)
'xq12- 12
- 2
'
- Per default ecerything ins put in an enclosing '' element. Also per default lists are converted
- to collecitons of `- ` elements. But by provding a mapping between list names and element names,
- you van generate different elements::
+ Per default everything is put in an enclosing '' element. Also per default lists are converted
+ to collections of `
- ` elements. By provding a mapping between list names and element names,
+ you can generate different elements:
>>> data = {"positionen": [{"m": 12}, {"m": 2}]}
>>> root = dict2et(data, roottag='xml')
@@ -255,6 +265,11 @@ def dict2et(xmldict, roottag='data', listnames=None):
>>> ET.tostring(root)
'122'
+ If you explictly set the elementname to None, a flat list is created:
+ >>> root = dict2et(data, roottag='flat', listnames={'positionen': None})
+ >>> ET.tostring(root)
+ '122'
+
>>> data = {"kommiauftragsnr":2103839, "anliefertermin":"2009-11-25", "prioritaet": 7,
... "ort": u"Hücksenwagen",
... "positionen": [{"menge": 12, "artnr": "14640/XL", "posnr": 1},],
@@ -285,12 +300,14 @@ def dict2et(xmldict, roottag='data', listnames=None):
7
2103839
'''
+
+ Sorting can be disabled which is only useful for collections.OrderedDict.
"""
if not listnames:
listnames = {}
root = ET.Element(roottag)
- _convert_dict_to_xml_recurse(root, xmldict, listnames)
+ _convert_dict_to_xml_recurse(root, xmldict, listnames, sort=sort)
return root
@@ -304,12 +321,12 @@ def list2et(xmllist, root, elementname):
return basexml.find(root)
-def dict2xml(datadict, roottag='data', listnames=None, pretty=False):
+def dict2xml(datadict, roottag='data', listnames=None, pretty=False, sort=True):
"""Converts a dictionary to an UTF-8 encoded XML string.
See also dict2et()
"""
- root = dict2et(datadict, roottag, listnames)
+ root = dict2et(datadict, roottag, listnames, sort=sort)
return to_string(root, pretty=pretty)
diff --git a/setup.py b/setup.py
index 4498a74..3bfb30a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
from distutils.core import setup
-version = '0.63'
+version = '0.64'
setup(
name='huTools',