0

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?

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.