Python list for XML and vice versa

I have python code that I wrote to convert a python list to an XML element. This is intended to interact with LabVIEW, hence the strange XML array format. Anyway, here is the code:

def pack(data): # create the result element result = xml.Element("Array") # report the dimensions ref = data while isinstance(ref, list): xml.SubElement(result, "Dimsize").text = str(len(ref)) ref = ref[0] # flatten the data while isinstance(data[0], list): data = sum(data, []) # pack the data for d in data: result.append(pack_simple(d)) # return the result return result 

Now I need to write an unpack () method to convert a packed XML array to a python list. I can extract the dimensions of the array and the data is just fine:

 def unpack(element): # retrieve the array dimensions and data lengths = [] data = [] for entry in element: if entry.text == "Dimsize": lengths.append(int(entry.text)) else: data.append(unpack_simple(entry)) # now what? 

But I'm not sure how unflatten the array is. What would be an effective way to do this?

Edit: this is what the python list and related XML look like. Note: arrays are n-dimensional.

 data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] 

And then the XML version:

 <Array> <Dimsize>2</Dimsize> <Dimsize>2</Dimsize> <Dimsize>2</Dimsize> <I32> <Name /> <Val>1</Val> </I32> ... 2, 3, 4, etc. </Array> 

The actual format is not important, but I just don’t know how to uncheck the box with:

 data = [1, 2, 3, 4, 5, 6, 7, 8] 

back to:

 data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]] 

Given:

 lengths = [2, 2, 2] 

Suppose pack_simple () and unpack_simple () do the same thing as pack () and unpack () for basic data types (int, long, string, boolean).

+4
source share
2 answers

Try the following:

 from operator import mul def validate(array, sizes): if reduce(mul, sizes) != len(array): raise ValueError("Array dimension incompatible with desired sizes") return array, sizes def reshape(array, sizes): for s in sizes: array = [array[i:i + s] for i in range(0, len(array), s)] return array[0] data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] length = [2, 2, 3] print reshape(validate(data, length)) length = [2, 2, 2] print reshape(validate(data, length)) 

Exit:

 [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]] Traceback: (...) ValueError: Array dimension incompatible with desired sizes 

An alternative is to use numpy arrays. Note that for this simple task, numpy is a pretty big dependency, although you will find that most of the (common) tasks / problems associated with the array already have an implementation there:

 from numpy import array print array(data).reshape(*length) # optionally add .tolist() to convert to list 

EDIT : added data validation

EDIT : example using numpy arrays (thanks to JFSebastian for the tip)

+2
source

start inside out:

 def group(seq, k): return [seq[i:i+k] for i in range(0, len(seq), k)] unflattened = group(group(data, 2), 2) 

Your example might be simpler if your measurements are not all the same. But I think the above code should work.

+2
source

All Articles