How do I get Python's ElementTree to pretty print to an XML file?

后端 未结 5 1085
猫巷女王i
猫巷女王i 2020-11-28 10:31

Background

I am using SQLite to access a database and retrieve the desired information. I\'m using ElementTree in Python version 2.6 to create an XML file with tha

相关标签:
5条回答
  • 2020-11-28 10:58

    I found a way using straight ElementTree, but it is rather complex.

    ElementTree has functions that edit the text and tail of elements, for example, element.text="text" and element.tail="tail". You have to use these in a specific way to get things to line up, so make sure you know your escape characters.

    As a basic example:

    I have the following file:

    <?xml version='1.0' encoding='utf-8'?>
    <root>
        <data version="1">
            <data>76939</data>
        </data>
        <data version="2">
            <data>266720</data>
            <newdata>3569</newdata>
        </data>
    </root>
    

    To place a third element in and keep it pretty, you need the following code:

    addElement = ET.Element("data")             # Make a new element
    addElement.set("version", "3")              # Set the element's attribute
    addElement.tail = "\n"                      # Edit the element's tail
    addElement.text = "\n\t\t"                  # Edit the element's text
    newData = ET.SubElement(addElement, "data") # Make a subelement and attach it to our element
    newData.tail = "\n\t"                       # Edit the subelement's tail
    newData.text = "5431"                       # Edit the subelement's text
    root[-1].tail = "\n\t"                      # Edit the previous element's tail, so that our new element is properly placed
    root.append(addElement)                     # Add the element to the tree.
    

    To indent the internal tags (like the internal data tag), you have to add it to the text of the parent element. If you want to indent anything after an element (usually after subelements), you put it in the tail.

    This code give the following result when you write it to a file:

    <?xml version='1.0' encoding='utf-8'?>
    <root>
        <data version="1">
            <data>76939</data>
        </data>
        <data version="2">
            <data>266720</data>
            <newdata>3569</newdata>
        </data> <!--root[-1].tail-->
        <data version="3"> <!--addElement's text-->
            <data>5431</data> <!--newData's tail-->
        </data> <!--addElement's tail-->
    </root>
    

    As another note, if you wish to make the program uniformally use \t, you may want to parse the file as a string first, and replace all of the spaces for indentations with \t.

    This code was made in Python3.7, but still works in Python2.7.

    0 讨论(0)
  • 2020-11-28 10:58

    If one wants to use lxml, it could be done in the following way:

    from lxml import etree
    
    xml_object = etree.tostring(root,
                                pretty_print=True,
                                xml_declaration=True,
                                encoding='UTF-8')
    
    with open("xmlfile.xml", "wb") as writter:
        writter.write(xml_object)`
    

    If you see xml namespaces e.g. py:pytype="TREE", one might want to add before the creation of xml_object

    etree.cleanup_namespaces(root) 
    

    This should be sufficient for any adaptation in your code.

    0 讨论(0)
  • 2020-11-28 11:01

    Whatever your XML string is, you can write it to the file of your choice by opening a file for writing and writing the string to the file.

    from xml.dom import minidom
    
    xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="   ")
    with open("New_Database.xml", "w") as f:
        f.write(xmlstr)
    

    There is one possible complication, especially in Python 2, which is both less strict and less sophisticated about Unicode characters in strings. If your toprettyxml method hands back a Unicode string (u"something"), then you may want to cast it to a suitable file encoding, such as UTF-8. E.g. replace the one write line with:

    f.write(xmlstr.encode('utf-8'))
    
    0 讨论(0)
  • 2020-11-28 11:03

    Take a look at the vkbeautify module.

    Input and output can be string/file in any combinations. It is very compact and doesn't have any dependency.

    import vkbeautify as vkb
    
    a) pretty_text = vkb.xml(your_xml_text)  #return String   
    
    b) vkb.xml(your_xml_text, 'path/to/dest/file') #save in file 
    
    0 讨论(0)
  • 2020-11-28 11:05

    Install bs4

    pip install bs4
    

    Use this code to pretty print:

    from bs4 import BeautifulSoup
    
    x = your xml
    
    print(BeautifulSoup(x, "xml").prettify())
    
    0 讨论(0)
提交回复
热议问题