Convert elementtree to dict
def elementtree_to_dict(element):
    d = dict()


I'd avoid the name d its not very helpful

    if hasattr(element, 'text') and  element.text is not None:
        d['text'] = element.text


getattr has a third parameter, default. That should allow you to simplify this piece of code a bit

    d.update(element.items()) # element's attributes

    for c in list(element): # element's children


The list does nothing, except waste memory.

        if c.tag not in d: 
            d[c.tag] = elementtree_to_dict(c)
        # an element with the same tag was already in the dict
        else: 
            # if it's not a list already, convert it to a list and append
            if not isinstance(d[c.tag], list):  
                d[c.tag] = [d[c.tag], elementtree_to_dict(c)]
           # append to the list
            else: 
                d[c.tag].append(elementtree_to_dict(c))


Yeah this whole block is a mess. Two notes:


Put everything in lists to begin with, and then take them out at the end
call elementtree_to_dict once

return d



This whole piece of code looks like a bad idea. 

&lt;foo&gt;
   &lt;bar id="42"/&gt;
&lt;/foo&gt;


Becomes

{"bar" : {"id": 42}}


Whereas

&lt;foo&gt;
    &lt;bar id="42"/&gt;
    &lt;bar id="36"/&gt;
&lt;/foo&gt;


Becomes

{"bar" : [{"id" : 42}, {"id": 36}]}


The XML schema is the same, but the python "schema" will be different. It'll be annoying writing code that correctly handles both of these cases.

Having said that, here's my cleanup of your code:

def elementtree_to_dict(element):
    node = dict()

    text = getattr(element, 'text', None)
    if text is not None:
        node['text'] = text

    node.update(element.items()) # element's attributes

    child_nodes = {}
    for child in element: # element's children
        child_nodes.setdefault(child, []).append( elementtree_to_dict(child) )

    # convert all single-element lists into non-lists
    for key, value in child_nodes.items():
        if len(value) == 1:
             child_nodes[key] = value[0]

    node.update(child_nodes.items())

    return node