docs: 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