code: def build_tree(self, data, tagname, attrs=None, depth=0):
          r
          if data is None:
              data = ''
          indent = ('\n%s' % (self.__options['indent'] * depth)) if self.__options['indent'] else ''
          if isinstance(data, utils.DictTypes):
              if self.__options['hasattr'] and self.check_structure(data.keys()):
                  attrs, values = self.pickdata(data)
                  self.build_tree(values, tagname, attrs, depth)
              else:
                  self.__tree.append('%s%s' % (indent, self.tag_start(tagname, attrs)))
                  iter = data.iteritems()
                  if self.__options['ksort']:
                      iter = sorted(iter, key=lambda x:x[0], reverse=self.__options['reverse'])
                  for k, v in iter:
                      attrs = {}
                      if self.__options['hasattr'] and isinstance(v, utils.DictTypes) and self.check_structure(v.keys()):
                          attrs, v = self.pickdata(v)
                      self.build_tree(v, k, attrs, depth+1)
                  self.__tree.append('%s%s' % (indent, self.tag_end(tagname)))
          elif utils.is_iterable(data):
              for v in data:
                  self.build_tree(v, tagname, attrs, depth)
          else:
              self.__tree.append(indent)
              data = self.safedata(data, self.__options['cdata'])
              self.__tree.append(self.build_tag(tagname, data, attrs))
docs: r"""Build xml tree.
  
          :param data: data for build xml.
          :param tagname: element tag name.
          :param attrs: element attributes. Default：``None``.
          :type attrs: dict or None
          :param depth: element depth of the hierarchy. Default：``0``.
          :type depth: int