Python code to write XML strange way to close the elements

Question:

I have a python code that write a XML file. The commands I use are similar to this:

import xml.etree.ElementTree as ET
import requests
import json
import csv
import random

data = ET.Element('DemoXML')
elementorderrequest = ET.SubElement(data, 'OrderRequest')

element0items = ET.SubElement(elementorderrequest, 'Items')
element0itemline1 = ET.SubElement(element0items, 'Item lineNumber="1"')

element0unitprice1 = ET.SubElement(element0itemline1, 'UnitPrice')
element0unitprice1.text = “51.09”

b_xml = ET.tostring(data)
 
with open("items2.xml", "wb") as f:
    f.write(b_xml)

The problem is in specific with the elements as ‘element0itemline1’. Check how it closes the element in the resulting file:

<Items>
    <Item lineNumber="1">
        <UnitPrice>51.09</UnitPrice>
    </Item lineNumber="1">
</Items>

The problem is the server rejects this way to close the element:

</Item lineNumber="1">

The server works if is entered like this:

</Item>

In other words a resulting file like this would be accepted:

<Items>
    <Item lineNumber="1">
        <UnitPrice>51.09</UnitPrice>
    </Item>
</Items>

How can be configured the python code or the element there to give </Item> and NOT </Item lineNumber="1">

I entered like this:

element0itemline1 = ET.SubElement(element0items, 'Item', 'lineNumber="1"')

But gives the error:

   element0itemline1 = ET.SubElement(element0items, 'Item', 'lineNumber="1"')
TypeError: SubElement() argument 3 must be dict, not str

Then how can be solved?

Asked By: Alex Co

||

Answers:

The crux of the issue is that SubElement() is interpreting your string as the entire name of the element. You need to pass in the attributes as parameters.

import xml.etree.ElementTree as ET

data = ET.Element('DemoXML')
elementorderrequest = ET.SubElement(data, 'OrderRequest')
element0items = ET.SubElement(elementorderrequest, 'Items')
element0itemline1 = ET.SubElement(element0items, 'Item', {"lineNumber":"1"})
element0unitprice1 = ET.SubElement(element0itemline1, 'UnitPrice')
element0unitprice1.text = "51.09"

b_xml = ET.tostring(data)
 
with open("items2.xml", "wb") as f:
    f.write(b_xml)

generate a file for me:

<DemoXML>
  <OrderRequest>
    <Items>
      <Item lineNumber="1">
        <UnitPrice>51.09</UnitPrice>
      </Item>
    </Items>
  </OrderRequest>
</DemoXML>
Answered By: JonSG
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.