# -*- coding: utf-8 -*-
import lxml.etree as etree
import xml.dom.minidom as minidom


class XML_base(object):
    @staticmethod
    def create_tag(name, text='', **kwargs):
        et = ElementTree.Element(name, **kwargs)
        et.text = text
        return et

    @staticmethod
    def to_format_str(xml_tree):
        formatter = xmlformatter.Formatter()
        rough_string = ElementTree.tostring(xml_tree, 'UTF-8')
        rough_string = unescape(rough_string)
        return formatter.format_string(rough_string)

    @staticmethod
    def parse(filepath):
        return etree.parse(filepath).getroot()

    @staticmethod
    def parse_string(xmlstr):
        return etree.fromstring(xmlstr)

    def to_xml(self):
        raise Exception('Need override')

    def to_str(self):
        return self.to_format_str(self.to_xml())

    def __str__(self):
        lines = self.to_str().split('\n')
        return '\n'.join(lines[1:])
@@ -113,32 +113,51 @@
    @staticmethod
+%0A%0A    @staticmethod
 %0A    def create_
@@ -175,10 +175,12 @@
 ext=
-''
+None
 , **
@@ -201,24 +201,18 @@
    et = 
-ElementT
+et
 ree.Elem
@@ -325,54 +325,131 @@
 tree
-):%0A        formatter = xmlformatter.Formatter(
+, pretty_text=True):%0A        indent = %22  %22%0A        if pretty_text:%0A            XML_base.pretty_text(xml_tree, indent=indent
 )%0A  
@@ -446,37 +446,35 @@
 indent)%0A        
-rough
+xml
 _string = Elemen
@@ -471,16 +471,10 @@
 g = 
-ElementT
+et
 ree.
@@ -494,17 +494,8 @@
 tree
-, 'UTF-8'
 )%0A  
@@ -500,21 +500,19 @@
         
-rough
+xml
 _string 
@@ -517,83 +517,92 @@
 g = 
-unescape(rough_string)%0A        return formatter.format_string(rough_string)
+minidom.parseString(xml_string).toprettyxml(indent=indent)%0A        return xml_string
 %0A%0A  
@@ -779,16 +779,655 @@
 mlstr)%0A%0A
+    @staticmethod%0A    def pretty_text(elem, indent=%22  %22, level=0):%0A        i = %22%5Cn%22 + level * indent%0A%0A        if len(elem) == 0:%0A            if elem.text is not None:%0A                lines = elem.text.split('%5Cn')%0A                if len(lines) %3E 1:%0A                    if not lines%5B0%5D.startswith(' '):%0A                        lines%5B0%5D = (i + indent) + lines%5B0%5D%0A                    if lines%5B-1%5D.strip() == '':%0A                        lines.pop()%0A                    elem.text = (i + indent).join(lines) + i%0A        else:%0A            for subelem in elem:%0A                XML_base.pretty_text(subelem, indent, level + 1)%0A%0A        return elem%0A%0A
     def 
@@ -1497,24 +1497,67 @@
  to_str(self
+, pretty_text=True, remove_first_line=False
 ):%0A        r
@@ -1555,22 +1555,24 @@
         
-return
+xmlstr =
  self.to
@@ -1600,34 +1600,69 @@
 ml()
-)%0A%0A    def __str__(self):%0A
+, pretty_text=pretty_text)%0A        if remove_first_line:%0A    
     
@@ -1690,33 +1690,41 @@
 tr().split('%5Cn')
-%0A
+%5B1:%5D%0A    
         return '
@@ -1737,13 +1737,153 @@
 in(lines
-%5B1:%5D
+)%0A        else:%0A            return xmlstr%0A%0A    def __str__(self):%0A        # remove version tag%0A        return self.to_str(remove_first_line=True
 )

use lxml & change pretty print method