python
38 lines · 9 steps
Converting nested dicts to XML in Python
A recursive builder turns dictionaries, lists, and scalars into an ElementTree structure, then serializes it to formatted XML.
Explained by
highlit
1from xml.etree import ElementTree as ET
2from xml.dom import minidom
3
4
5def dict_to_element(tag, value):
6 element = ET.Element(tag)
7
8 if isinstance(value, dict):
9 attrs = value.pop("@attributes", None)
10 if isinstance(attrs, dict):
11 for name, attr_value in attrs.items():
12 element.set(name, str(attr_value))
13
14 text = value.pop("#text", None)
15 if text is not None:
16 element.text = str(text)
17
18 for key, child_value in value.items():
19 if isinstance(child_value, list):
20 for item in child_value:
21 element.append(dict_to_element(key, item))
22 else:
23 element.append(dict_to_element(key, child_value))
24 elif isinstance(value, (list, tuple)):
25 for item in value:
26 element.append(dict_to_element("item", item))
27 elif value is not None:
28 element.text = str(value)
29
30 return element
31
32
33def dict_to_xml(root_tag, data, pretty=True):
34 root = dict_to_element(root_tag, data)
35 rough = ET.tostring(root, encoding="unicode")
36 if not pretty:
37 return rough
38 return minidom.parseString(rough).toprettyxml(indent=" ")
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Recursion mirrors the shape of nested data, letting one function handle arbitrary depth.
- 2Reserved key conventions like @attributes and #text let a flat dict encode XML's attribute-and-text model.
- 3Building a tree first and serializing last cleanly separates structure from formatting concerns.
Related explainers
python
from fastapi import FastAPI, WebSocket, WebSocketDisconnect app = FastAPI()
Building a WebSocket chat with FastAPI
websockets
broadcast
connection-management
Intermediate
9 steps
python
import time import uuid from django.utils.deprecation import MiddlewareMixin
Attaching per-request context in Django
middleware
request lifecycle
multi-tenancy
Intermediate
7 steps
javascript
function evaluate(expression) { const tokens = tokenize(expression); let pos = 0;
Building a recursive descent calculator
parsing
recursion
operator-precedence
Intermediate
8 steps
rust
use axum::{ extract::{Path, State}, response::sse::{Event, KeepAlive, Sse}, };
Streaming import progress with SSE in Axum
server-sent-events
streams
watch-channel
Advanced
7 steps
python
import random from typing import Iterator, List
How reservoir sampling picks k items
reservoir-sampling
streaming
randomness
Intermediate
5 steps
python
import secrets from django.contrib.auth import authenticate, login from django.core.cache import cache
Two-factor login with OTP in Django
two-factor-auth
one-time-passwords
caching
Intermediate
9 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/converting-nested-dicts-to-xml-in-python-explained-python-7f5d/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.