Reputation: 19
I want to create an XML file using python like this:
<?xml version="1.0" encoding="utf-8"?>
<vehicle id="m0">
<timestep pos="2.3000" angle="11.1766" lane="-250709918#7_0" speed="0.0000" time="8.0"
</vehicle>
<vehicle id="m1">
<timestep pos="2.3000" angle="11.1766" lane="-250709918#7_0" speed="0.0000" time="8.0"
</vehicle>
........
my code:
doc = xml.dom.minidom.Document()
root = doc.createElement('vehicle')
for veh in veh_dict:
root.setAttribute('id', veh)
doc.appendChild(root)
for index, value in enumerate(veh_dict[veh]):
nodeManager = doc.createElement('timestep')
nodeManager.setAttribute('time', str(veh_dict[veh][index]['time']))
nodeManager.setAttribute('angle', str(veh_dict[veh][index]['angle']))
nodeManager.setAttribute('lane', str(veh_dict[veh][index]['lane']))
nodeManager.setAttribute(' pos', str(veh_dict[veh][index]['pos']))
nodeManager.setAttribute('speed', str(veh_dict[veh][index]['speed']))
nodeManager.setAttribute('type', str(veh_dict[veh][index]['type']))
nodeManager.setAttribute('x', str(veh_dict[veh][index]['x']))
nodeManager.setAttribute('y', str(veh_dict[veh][index]['y']))
root.appendChild(nodeManager)
fp = open('Manager.xml', 'w')
doc.writexml(fp, indent='\t', addindent='\t', newl='\n', encoding="utf-8")
My output has all datas, but they are all written in one of the 'vehicle' like this:
<vehicle id="m2.9">
<timestep pos="2.3000" angle="11.1766" lane="-250709918#7_0" speed="0.0000" time="8.0" type="custom_moto" x="469.2605" y="5896.8761"/>
<timestep pos="3.3001" angle="12.9664" lane="-250709918#7_0" speed="1.0001" time="9.0" type="custom_moto" x="470.1134" y="5907.0132"/>
<timestep pos="6.4467" angle="12.2144" lane="-250709918#7_0" speed="3.1466" time="10.0" type="custom_moto" x="470.849" y="5900.3489"/>
<timestep pos="12.7147" angle="11.8696" lane="-250709918#7_0" speed="6.2681" time="11.0"
.......
Is the root always being overwritten? How can solve it?
Upvotes: 1
Views: 1650
Reputation: 107577
Consider using a top-level root above <vehicle>
elements as required for well-formed XML documents. Also, avoid the repetitious lines and use the inner dictionary keys as the iterator variable. Finally, use context manager, with
, to write built XML to file.
import xml.dom.minidom
# LIST OF DICTS
veh_dicts = [{'x': '469.2605', 'y': '5896.8761', 'time': 8.0, 'lane': '-250709918#7_0',
'angle': '11.1766', 'pos': '2.3000', 'speed': '0.0000', 'type': 'custom_moto'},
{'x': '470.1134', 'y': '5907.0132', 'time': 9.0, 'lane': '-250709918#7_0',
'angle': '12.9664', 'pos': '3.3001', 'speed': '1.0001', 'type': 'custom_moto'}]
doc = xml.dom.minidom.Document()
root = doc.createElement('vehicles') # TOP-LEVEL ROOT
doc.appendChild(root)
# ITERATE THROUGH EACH DICT
for i, veh in enumerate(veh_dicts, start=1):
vehichleElem = doc.createElement('vehicle')
vehichleElem.setAttribute('id', f'm{i}') # USES F-STRING (Python 3.6+)
root.appendChild(vehichleElem)
nodeManager = doc.createElement('timestep')
for k in veh.keys():
nodeManager.setAttribute(k, str(veh[k]))
vehichleElem.appendChild(nodeManager)
with open('MiniDomXMLBuild.xml', 'w') as fp: # CONTEXT MANAGER (NO close() NEEDED)
doc.writexml(fp, addindent='\t', newl='\n', encoding="utf-8")
Output
<?xml version="1.0" encoding="utf-8"?>
<vehicles>
<vehicle id="m1">
<timestep angle="11.1766" lane="-250709918#7_0" pos="2.3000" speed="0.0000" time="8.0" type="custom_moto" x="469.2605" y="5896.8761"/>
</vehicle>
<vehicle id="m2">
<timestep angle="12.9664" lane="-250709918#7_0" pos="3.3001" speed="1.0001" time="9.0" type="custom_moto" x="470.1134" y="5907.0132"/>
</vehicle>
</vehicles>
Upvotes: 0
Reputation: 5476
Add the root element inside the loop:
import xml.dom.minidom
doc = xml.dom.minidom.Document()
topElem = doc.createElement('vehicles')
for veh in veh_dict:
for index, value in enumerate(veh_dict[veh]):
root = doc.createElement('vehicle')
root.setAttribute('id', veh)
doc.appendChild(root)
nodeManager = doc.createElement('timestep')
nodeManager.setAttribute('time', str(veh_dict[veh][index]['time']))
nodeManager.setAttribute('angle', str(veh_dict[veh][index]['angle']))
nodeManager.setAttribute('lane', str(veh_dict[veh][index]['lane']))
nodeManager.setAttribute(' pos', str(veh_dict[veh][index]['pos']))
nodeManager.setAttribute('speed', str(veh_dict[veh][index]['speed']))
nodeManager.setAttribute('type', str(veh_dict[veh][index]['type']))
nodeManager.setAttribute('x', str(veh_dict[veh][index]['x']))
nodeManager.setAttribute('y', str(veh_dict[veh][index]['y']))
root.appendChild(nodeManager)
topElem.appendChild(root)
fp = open('Manager.xml', 'w')
doc.writexml(fp, indent='\t', addindent='\t', newl='\n', encoding="utf-8")
Upvotes: 2