docs: def xml2dict(xml, sanitize=True, prefix=None):
      """Return XML as dict.
  
      >>> xml2dict('<?xml version="1.0" ?><root attr="name"><key>1</key></root>')
      {'root': {'key': 1, 'attr': 'name'}}
  
      """
      from xml.etree import cElementTree as etree  # delayed import
  
      at = tx = ''
      if prefix:
          at, tx = prefix
  
      def astype(value):
          # return value as int, float, bool, or str
          for t in (int, float, asbool):
              try:
                  return t(value)
              except Exception:
                  pass
          return value
  
      def etree2dict(t):
          # adapted from https://stackoverflow.com/a/10077069/453463
          key = t.tag
          if sanitize:
              key = key.rsplit('}', 1)[-1]
          d = {key: {} if t.attrib else None}
          children = list(t)
          if children:
              dd = collections.defaultdict(list)
              for dc in map(etree2dict, children):
                  for k, v in dc.items():
                      dd[k].append(astype(v))
              d = {key: {k: astype(v[0]) if len(v) == 1 else astype(v)
                         for k, v in dd.items()}}
          if t.attrib:
              d[key].update((at + k, astype(v)) for k, v in t.attrib.items())
          if t.text:
              text = t.text.strip()
              if children or t.attrib:
                  if text:
                      d[key][tx + 'value'] = astype(text)
              else:
                  d[key] = astype(text)
          return d
  
      return etree2dict(etree.fromstring(xml))