Reputation: 181
I'm trying to write an xml file with ElementTree. GeeksforGeeks have a great tutorial for that. The problem i'm facing is that I want to write multiple xml structures in the same xml file.
The xml file that is created during the tutorial is as follows:
Current output
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
What I want to create with a loop is the following:
Desired output
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
I've tried to use a loopfunction and the loop is working but the writing to an xml file isn't working. my code looks like this.
CODE
import xml.etree.ElementTree as ET
test = [1,2,3]
l = []
for i in test:
data = ET.Element('chess')
element1 = ET.SubElement(data, 'Opening')
s_elem1 = ET.SubElement(element1, 'E4')
s_elem2 = ET.SubElement(element1, 'D4')
s_elem1.set('type', 'Accepted')
s_elem2.set('type', 'Declined')
s_elem1.text = "King's Gambit Accepted"
s_elem2.text = "Queen's Gambit Declined"
b_xml = ET.tostring(data)
l.append(b_xml)
output = bytearray(l)
with open("output.xml", "wb") as f:
f.write(l)
Error message
TypeError: an integer is required
Is there a way to create multiple structures in one xml file and write it to an output file?
Upvotes: 0
Views: 650
Reputation: 18106
You need to have at least one root element in XML, to append the children to:
from lxml import etree
test = [1, 2, 3]
l = []
xmlRoot = etree.Element('root')
for i in test:
data = etree.SubElement(xmlRoot, 'chess')
element1 = etree.SubElement(data, 'Opening')
s_elem1 = etree.SubElement(element1, 'E4')
s_elem2 = etree.SubElement(element1, 'D4')
s_elem1.set('type', 'Accepted')
s_elem2.set('type', 'Declined')
s_elem1.text = "King's Gambit Accepted"
s_elem2.text = "Queen's Gambit Declined"
doc = etree.ElementTree(xmlRoot) # convert into elementtree and write it directly into a file
with open("output.xml", "wb") as f:
f.write(
etree.tostring(
doc, pretty_print=True, xml_declaration=True, encoding='utf-8'
)
)
print(open("output.xml").read())
Out:
<?xml version='1.0' encoding='utf-8'?>
<root>
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
<chess>
<Opening>
<E4 type="Accepted">King's Gambit Accepted</E4>
<D4 type="Declined">Queen's Gambit Declined</D4>
</Opening>
</chess>
</root>
Upvotes: 1