XML to Pydantic BaseModel Generator — Offline
Paste an XML document and get Pydantic v2 models in milliseconds: nested elements become nested BaseModel classes, attributes become aliased fields, ISO-8601 timestamps become datetime, and repeated elements become lists. Generation runs in a Web Worker inside your browser — the documents you would never paste into a random site stay on your machine.
Zero upload, ever
Parsing and generation run in a Web Worker inside your browser — SOAP envelopes, invoices, and records with PII never touch a server.
Live 300 ms conversion
Output updates as you type, with repeated elements inferred as arrays, mixed content preserved, and ISO-8601 dates mapped natively.
Idiomatic Pydantic output
Generated with target-native conventions — renamed identifiers, preserved original-key mappings, and imports you would have written by hand.
Paste XML to generate a schema
XML input
Generated schema
Paste XML on the left — Zod, TypeScript, Pydantic, and Go schemas appear here instantly, generated entirely in your browser.
Technical documentation
Pydantic models with aliases that round-trip
Pydantic v2 made aliases first-class, and XML is the reason that matters: attributes carry names like @id and tags arrive as kebab-case, neither of which is a legal Python identifier. The generator maps each one to a clean field name and records the original as a Field alias, so model_validate on the converted structure — and model_dump back toward it — preserves the exact source names. The alias is not cosmetic; it is the contract that keeps the model loadable and the data round-trippable.
Nesting maps the way you would design it by hand: each repeating or nested element becomes its own BaseModel, repeated siblings become list[T], and empty elements become Optional fields, because absence in XML is a fact the type system should admit. The output is idiomatic v2 — no legacy Config classes, no v1 quirks to strip before committing.
Configuration is generated too: model_config settings for populating by alias are emitted where the source requires them, so populate_by_name behaves the way the XML expects rather than the way a template defaulted. Small detail, real consequence — it is the difference between a model that imports clean and a model that round-trips.
Typed honestly from evidence, not optimism
The type choices are conservative where wrong guesses are expensive: xs:boolean-style text (true/false) becomes bool, round-trippable numbers become int or float, and everything else stays str — including 007, version strings, and anything numeric-looking that does not round-trip. CDATA is always str, verbatim. ISO-8601 timestamps become datetime because Pydantic coerces them natively and they are the one text format where the payoff is unambiguous.
The known limit is stated rather than hidden: fields absent from your sample will not appear in the model, and a field seen once is typed as a scalar even if other documents repeat it. Feed the generator your richest instance — or two — and the merge is a five-minute edit in plain, readable model code.
A workflow worth copying: generate the models from a production sample, put them in a models.py beside the parser, and let Pydantic v2's validation errors become your integration tests. The first time an upstream feed quietly changes a type, the ValidationError names the field, the alias points back to the exact tag, and the fix is a one-line change instead of a debugging session.
Why offline conversion matters for XML payloads with PII
Enterprise XML is a compliance surface: purchase orders, patient feeds, identity payloads. This generator runs in a Web Worker inside your browser with no upload endpoint, no logging, and no account — the document is parsed on your machine and the models are generated on your machine, which is the only architecture where the privacy claim is unfalsifiable. Load the page, go offline, and it still converts. Feeds carrying PII — patient records, payroll, identity documents — are exactly what this tool keeps on your machine.
Every conversion is bounded by a 3-second watchdog and a nesting-depth limit, and malformed input produces a named diagnosis — mismatched tag, unknown entity, unterminated CDATA — with line and column, never a partial model that validates the wrong thing.
Frequently asked questions
How do I convert XML to a Pydantic model?
Paste the XML into the input pane, pick Pydantic as the target, and the BaseModel classes generate live as you type. Set the root name in the workspace to control the top-level class name, then copy the output into your project.
How are XML attributes represented?
Attributes become model fields with clean names and Field(alias=...) mappings back to the original @-prefixed or kebab-case source names, so validation and serialization round-trip without losing the wire format. Attribute values are sniffed conservatively: true/false and round-trippable numbers get bool/int/float types, everything else stays str.
Do ISO timestamps become datetime fields?
Yes — text matching ISO-8601 maps to datetime, which Pydantic coerces natively on validation. Non-ISO dates ("01/15/2024", "15 Oct 26") stay str, because guessing formats is how validators reject the data they were written to accept.
Can it handle SOAP envelopes and namespaced tags?
Yes — namespaced tags are preserved through parsing and renamed to valid Python identifiers with aliases recording the original, so soap:Body and atom:feed stay distinguishable. The namespace itself is treated as part of the name rather than stripped, which is what keeps two same-named elements from different namespaces from collapsing into one field.
Is my XML uploaded anywhere?
Never. Parsing and model generation run entirely in your browser inside a Web Worker — no upload endpoint exists, nothing is logged, and the page keeps working offline. Malformed XML yields precise line-and-column errors instead of a wrong model.