Python how to serialize xml objects within objects

Question:

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?

Asked By: Joel

||

Answers:

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>
Answered By: CryptoFool
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.