Skip line in XML with Python

Asked

Viewed 179 times

0

Hello! I am creating a program in Python where the output of the program will be an XML script in the ABAP language (for a SAP specific transport), but when I export the output to XML it does not export identada, that is, everything in the same line.

How does it come out:

<lista><usuario><user name="user">admin</user><senha name="senha">123456</senha><nome name="nome">Fulano de Tal</nome></usuario></lista>

How I want it to go:

<lista>
   <usuario>
       <user name="user">admin</user>
       <senha name="senha">123456</senha>
       <nome name="nome">Fulano de Tal</nome>
   </usuario>
</lista>

The code I’m using:

import xml.etree.cElementTree as ET
class XML(object):
 def __init__(self, usuario, senha, nome):
    self.usuario = usuario
    self.senha = senha
    self.nome = nome

 def gerar_xml(self):    
    lista = ET.Element("lista")
    no_usuario = ET.SubElement(lista, "usuario")
    ET.SubElement(no_usuario, "user", name="user").text = self.usuario
    ET.SubElement(no_usuario, "senha", name="senha").text = self.senha
    ET.SubElement(no_usuario, "nome", name="nome").text = self.nome                
    arquivo = ET.ElementTree(lista)
    arquivo.write("meu_xml.xml")

def main():
  xml = XML("admin", "123456", "Fulano de Tal")
  xml.gerar_xml()    

main()

2 answers

1


Theoretically you don’t need to add these spaces. The XML format is meant to be consumed by other programs and not by humans, so you don’t need these line breaks and indentations. The program that will consume this XML will not complain, because XML is valid as it is. In addition, adding these indentations will increase the size of your file unnecessarily.

For these reasons, the module xml.etree python does not support this feature. If you still want to "beautify" your XML, you will have to use an alternative library to handle it. I suggest the excellent library lxml.etree, because it has a very similar API to the xml.etree, and you probably won’t need to rewrite anything.

Using the lxml, gets like this:

arquivo.write("meu_xml.xml", pretty_print=True)
  • 1

    It is pq in case, the user will have q take the contents of this generated XML and add in the Final script manually. And in the final script it’s idented, so to avoid confusion I chose to leave it that way too. I used the LXML API with the pretty_print command and it worked right! Thank you!

0

If you take a look in that question from Soen will know many interesting answers. I will leave here a brief summary of some responses and a python function to indent your XML if it is not possible to use another library:


Using xml.dom.minidom

import xml.dom.minidom

dom = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = dom.toprettyxml()

Using lxml

As @nosklo already mentioned in his reply:

import lxml.etree as etree

x = etree.parse("filename")
print etree.tostring(x, pretty_print=True)

Changing the text nodes of your XML

One of the options is to use a function to change the text nodes of your XML to indent the file. I advise you to modify the XML only for viewing.

def indent(elem, level=0):
    i = "\n" + level * "  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level + 1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

Code running on Repl.it

Browser other questions tagged

You are not signed in. Login or sign up in order to post.