Skip to content
100% Client-SideZero UploadGo Struct Output

XML to Go Struct Generator — Offline & Private

Paste an XML document and get Go structs with struct tags in milliseconds: nested elements become nested structs, repeated siblings become slices, attributes become tagged fields, and the original names live in the tags where encoding/xml expects them. The generator runs in a Web Worker inside your browser — nothing is uploaded, ever.

  • 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 Go Structs 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

Examples
100% Local Execution: Your PII never leaves this browser tab.

XML input

0 lines · 0 chars

Generated schema

Paste XML on the left — Zod, TypeScript, Pydantic, and Go schemas appear here instantly, generated entirely in your browser.

Technical documentation

Structs encoding/xml can actually unmarshal into

A Go struct is only as good as its tags when XML is on the other end, so this generator emits both halves: exported field names that satisfy Go's conventions and xml tags that satisfy the document's. Attributes become fields tagged with the ,attr option, character data becomes ,chardata where it appears, repeated elements become slices, and the root element name becomes the struct the unmarshaller starts from — the output is not inspired by the document, it is derived from it.

The element-to-field mapping is explicit in every tag, which is what makes the structs survive contact with real documents: when a feed adds an element, the diff shows the new tagged field, and when a tag name changes, the tag is where the fix lands. No reflection magic, no code generation beyond the structs themselves — paste, copy, unmarshal.

Pointers deserve one clarification: only empty elements infer pointer fields, not every optional-looking one. Go's nil is reserved for what the document actually showed as absent, which keeps JSON marshalling of the same structs predictable — pointers serialize as null, zero values serialize as values, and the XML told you which is which.

Slices, pointers, and Go's honest treatment of absence

Go distinguishes zero values from absence better than most type systems, and the generator leans on it: empty XML elements infer pointer fields so nil means absent, repeated elements become slices so one-or-many is encoded once, and text fields stay string unless the evidence is unambiguous — true/false becomes bool and round-trippable numbers become float64 or int, while 007 and version strings stay strings.

The limitation of instance inference applies here as everywhere: fields missing from your sample are missing from the struct, and a once-seen element types as a scalar even where other documents repeat it. The output is plain, gofmt-shaped struct code — paste the richest document you have, and hand-merging a second sample is a mechanical edit, not a rewrite.

The workflow that earns its keep: check the richest document you have into a testdata directory, generate the struct, and write the unmarshal test beside it. When a vendor changes the feed, the test fails before production does, and the struct tags show exactly which field moved. The generated code is ordinary Go — reviewable in a PR, diffable in a revert, and deletable without ceremony.

Why offline conversion matters for XML payloads with PII

The XML documents Go services consume — bank feeds, logistics manifests, SOAP intermediaries — are the documents you least want leaving your machine. This converter is architecturally incapable of exfiltrating them: parsing and generation run in a browser Web Worker, there is no upload path in the code, and the page functions offline as proof. No account, no telemetry, no quotes-about-security — just no network call. Manifests and bank feeds saturated with PII are exactly what this tool is architected to keep local.

Runaway documents hit a 3-second watchdog instead of a frozen tab, and malformed input is rejected with a line-and-column diagnosis — mismatched closing tags, unknown entities, unterminated CDATA — so you fix the document instead of debugging a struct that was generated from a misread.

Frequently asked questions

How do I convert XML to a Go struct?

Paste the XML document into the input pane and the struct generates live as you type, complete with xml struct tags. Set the root name in the workspace to control the top-level struct's name, then copy the output into your project and unmarshal straight into it.

Do the structs include xml tags?

Yes — every field carries an xml tag derived from the source document: attributes use the ,attr option, element names that are not valid Go identifiers are mapped through their tag, and repeated elements become slices. The tags are what make encoding/xml unmarshal the original document without manual field mapping.

How are repeated elements handled?

Elements that appear multiple times as siblings become slices in the struct; an element seen once becomes a plain field. That is inference from evidence — if another document repeats an element your sample shows once, paste that document too and promote the field to a slice by hand; the output is plain Go, so the edit is mechanical.

What about namespaces in the Go output?

Namespaced tags are preserved through parsing and the namespace prefix is carried into the struct tag mapping, so soap:Body and atom:feed remain distinguishable fields. Stripping prefixes silently is how two unrelated elements collapse into one field, so it never happens.

Is my XML uploaded to a server?

No. Parsing and struct generation run in a Web Worker inside your browser — no upload endpoint exists, nothing is logged, and the converter keeps working offline once the page is loaded. Malformed XML produces precise line-and-column errors rather than a wrong struct.