Python to XML Converter
Paste a Python class, dict, or dataclass. Get clean XML back.
What this tool does
If you have ever had to hand-craft an XML payload to mirror a Python class — for a SOAP endpoint, a config file, a legacy integration, or a test fixture — you already know the drill: fight xml.etree.ElementTree for an hour, then realise you forgot a nested field. Paste the Python here instead and you get back well-formed XML in one pass. A plain dict, a dataclass, a Pydantic model, or something deeply nested — same result.
It is not dumb string-replacement. The converter understands how Python values actually map to XML: Decimal("49.99") becomes plain numeric text, datetime and date come out as ISO-8601 strings, UUID becomes a standard 8-4-4-4-12 hex string, Optional[...] fields with None values become empty elements instead of being dropped, and list[T] or List[T] become container elements with one child per item, named after the item type — the same shape libraries like xmltodict or lxml would produce.
Type hints are honoured too. @dataclass field names become element names. Field(alias="x") on Pydantic models renames the element. field(metadata={"xml": "attribute"}) on a dataclass pushes the value to an attribute instead of a child element. Private fields starting with _ are dropped. If you paste several classes, each one lands in the output with nested types expanded and inherited attributes rolled in. Nothing gets silently swallowed — if a field is there, it shows up in the XML.
How to use it
Three steps. Works the same whether you paste a five-line dict or a whole models.py.
Paste your Python (or try the sample)
Drop your Python into the left editor as-is. A dict literal, a dataclass, a Pydantic BaseModel, nested classes, or an instance assignment — all fine. Click Load Sample if you want to see a realistic Order / OrderItem / Address example first.
Leave the imports, decorators, and type hints in. You do not need to strip them — the parser reads typing annotations and uses them to decide output types.
Hit Convert
Click the green Convert button. The tool reads the Python, preserves every class and attribute, and emits the XML in one pass. You will see a short loading indicator while it runs.
Copy the XML
The right panel fills with indented, well-formed XML that any standards-compliant XML parser will accept. Copy it straight into your SOAP request, config file, test fixture, or docs.
When this actually comes in handy
SOAP / legacy integration fixtures
You have a Pydantic request model and need an XML body to send to a legacy SOAP service. Paste the model, get the XML, paste it into your test runner — done.
Turning dataclasses into config
A Settings dataclass with 30 fields becomes a ready-to-edit XML config template for any XML-based settings store — no handwritten scaffolding, no typos.
Keeping XSD docs honest
Generate XML samples for your README, API reference, or XSD-backed schema docs straight from the actual models in your code, so the examples never drift from reality.
Seeding integration tests
Convert instance literals from your pytest fixtures into XML seed files for systems that still speak XML — legacy APIs, mock servers, or XSLT pipelines.
Common questions
Does it work with dataclasses, Pydantic, and plain dicts?
Yes, all three. @dataclass and Pydantic BaseModel get their field names used as element names. Plain dict literals work too — the keys become element names and values are emitted by type. Nested models or dicts are expanded as nested elements.
How does it handle Decimal, datetime, and UUID?
Decimal("49.99") becomes 49.99 as element text. datetime, date, and time come out as ISO-8601 strings. UUID becomes a standard 8-4-4-4-12 hex string. Enum subclasses emit their .value. Sets become container elements just like lists.
What about Optional[...] and None values?
Fields with a None value are written as empty elements (<field/>) rather than being dropped — the output shape stays consistent, which matters if a downstream XSD requires the element to be present.
Can I rename elements or push fields to attributes?
Yes. On Pydantic models, Field(alias="x") renames the element. On dataclasses, field(metadata={"xml": "attribute"}) pushes the field to an attribute on the parent, and metadata={"xml": "name", ...} renames it. Private fields prefixed with an underscore (_cache, _tmp) are dropped by default.
Can I paste multiple classes at once?
Yes — paste a whole models.py. Each top-level class comes through with nested types expanded and inherited fields from base classes included. If you also include an instance assignment, the instance is what gets serialized; otherwise the first class with resolvable defaults is used.
Is my code stored?
Your code is sent to the backend for conversion and is not persisted — we do not log the payload. As always with online tools, if the code is genuinely sensitive, look it over before pasting.
Other tools you may need
Python to XML is one piece of the puzzle. These pair well with it: