I'm trying to serialize a python object into xml. if I use dict2xml package it sort of works. Most of the fields in the object serialize to xml but I also have an object within the object that does not. It also doesn't put the main tags "person".
My objects:
@dataclass
class Person:
first_name: str
last_name: str
address: Address
@dataclass
class Address:
line1: str
city: str
state: str
zip: str
Returned XML:
<address>Address(line1='line1', city='city1', state='state1', zip='12345')</address>
<first_name>firstname</first_name>
<last_name>lastname</last_name>
code:
dict2xml(person.__dict__) # <-- person is instantiated Person with data
would like it to return:
<Person>
<address>
<line1>line1</line1>
<city>city1</city>
<state>state1</state>
<zip>12345</zip>
</address>
<first_name>firstname</first_name>
<last_name>lastname</last_name>
</Person>
Thoughts on how I can get the objects into my desired xml format?
CodePudding user response:
The dict2xml
module does not seem to provide any way to define how it should turn your class objects into dictionaries. So you have to do this yourself at all levels so that what you pass to the module consists only of standard Python dicts and lists.
Also, to get the outer <Person>
tag, you can utilize the optional wrap
parameter. Alternatively, you could create an outer dict with the key Person
to get that level from the data itself.
Here are both ways to get the output you desire:
from dataclasses import dataclass
import dict2xml as dict2xml
@dataclass
class Address:
line1: str
city: str
state: str
zip: str
@dataclass
class Person:
first_name: str
last_name: str
address: Address
person = Person("firstname", "lastname", Address("line1", "city1", "state1", "12345"))
pd = person.__dict__.copy()
pd['address'] = pd['address'].__dict__
print(dict2xml.dict2xml(pd, wrap="Person"))
# OR: print(dict2xml.dict2xml({'Person': pd}))
Result:
<Person>
<address>
<city>city1</city>
<line1>line1</line1>
<state>state1</state>
<zip>12345</zip>
</address>
<first_name>firstname</first_name>
<last_name>lastname</last_name>
</Person>