reverse of XML.as_dict(): Create a new XML element from the given element_data.
        Rules:
        * element_data is a dict with one key, which is the name of the element
            * The element name can be in "prefix:..."" form, if the namespace prefix is in self.NS
            * The element name can also be in "{namespace}..." form
        * element_data[key] is a list.
        * element_data[key][0] is a dict with the element's attributes
        * element_data[key][1:] are strings and dicts
            * strings are interpreted as text
            * dicts are interpreted as elements, which must follow the rules of element_data.
        * namespaces are applied from self.NS

def from_dict(Class, element_data, fn=None):
        """reverse of XML.as_dict(): Create a new XML element from the given element_data.
        Rules:
        * element_data is a dict with one key, which is the name of the element
            * The element name can be in "prefix:..."" form, if the namespace prefix is in self.NS
            * The element name can also be in "{namespace}..." form
        * element_data[key] is a list.
        * element_data[key][0] is a dict with the element's attributes
        * element_data[key][1:] are strings and dicts
            * strings are interpreted as text
            * dicts are interpreted as elements, which must follow the rules of element_data.
        * namespaces are applied from self.NS
        """
        from .builder import Builder

        B = Builder(default=Class.DEFAULT_NS, **Class.NS)
        keys = list(element_data.keys())
        assert len(keys) == 1
        key = keys[0]
        elem_tag = Class.dict_key_tag(key)
        elem = B(elem_tag)
        for k in element_data[key].keys():
            # attributes
            if k[0] == '@':
                attr_name = Class.dict_key_tag(k[1:])
                elem.set(attr_name, element_data[key][k])
            elif k == 'nodes':
                for node in element_data[key][k]:
                    if type(node) == str:
                        if len(elem) == 0:
                            elem.text = node
                        else:
                            elem[-1].tail = node
                    else:
                        child_elem = Class.from_dict(node)
                        elem.append(child_elem)
            else:
                raise ValueError('unsupported data: %r: %r' % (k, element_data[key][k]))
        return elem