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

def build_tree(self, data, tagname, attrs=None, depth=0):
        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
        """
        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))