Python Element Tree Writing to New File
Asked Answered
A

2

34

Hi so I've been struggling with this and can't quite figure out why I'm getting errors. Trying to export just some basic XML into a new file, keeps giving me a TypeError. Below is a small sample of the code:

from xml.etree.ElementTree import ElementTree
from xml.etree.ElementTree import Element
from xml.etree.ElementTree import SubElement
import xml.etree.ElementTree as ET


root = Element('QuoteWerksXML')
tree = ElementTree(root)
ver = SubElement(root, "AppVersionMajor")
ver.text = '5.1'

tree.write(open('person.xml', 'w'))
Aerostation answered 8/6, 2016 at 21:24 Comment(1)
Please post the whole traceback.Xeniaxeno
S
49

The ElementTree.write method defaults to us-ascii encoding and as such expects a file opened for writing binary:

The output is either a string (str) or binary (bytes). This is controlled by the encoding argument. If encoding is "unicode", the output is a string; otherwise, it’s binary. Note that this may conflict with the type of file if it’s an open file object; make sure you do not try to write a string to a binary stream and vice versa.

So either open the file for writing in binary mode:

with open('person.xml', 'wb') as f:
    tree.write(f)

or open the file for writing in text mode and give "unicode" as encoding:

with open('person.xml', 'w') as f:
    tree.write(f, encoding='unicode')

or open the file for writing in binary mode and pass an explicit encoding:

with open('person.xml', 'wb') as f:
    tree.write(f, encoding='utf-8')
Strongarm answered 8/6, 2016 at 21:30 Comment(2)
And if writing to standard output, you can use tree.write(sys.stdout.buffer).Dejecta
in my case encoding could not be 'unicode'. I had to change it to "UTF-8" insteadWrit
B
0

You can pass a filename to .write() method, i.e. you don't have to open a file object, so you can bypass the problem in the OP altogether by the following:

tree.write('person.xml')

On a side note, you can pass encoding, declaration, indentation (since Python 3.9) etc. as well.

from xml.etree.ElementTree import ElementTree
import xml.etree.ElementTree as ET
tree = ElementTree(ET.XML('<QuoteWerksXML><AppVersionMajor>5.1</AppVersionMajor></QuoteWerksXML>'))
ET.indent(tree)
tree.write("person.xml", encoding='utf-8', xml_declaration=True)

creates a file that looks like the following:

<?xml version='1.0' encoding='utf-8'?>
<QuoteWerksXML>
  <AppVersionMajor>5.1</AppVersionMajor>
</QuoteWerksXML>
Bigelow answered 24/3 at 4:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.