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?
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>
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?
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>