Go to XML Converter
Paste Go structs. Get clean XML back.
What this tool does
If you have ever had to assemble an XML payload that matches a Go struct — for a SOAP client, an RSS feed, a legacy SaaS webhook, or a vendor sitemap — you already know how fiddly it is. You can call xml.Marshal yourself, but that means wiring up main.go, compiling, and eyeballing the output. Paste the Go here instead and you get back well-formed XML in one step. One struct, a file with several, or a literal you copy-pasted out of Go by Example — same deal: a complete XML document with every field preserved.
It mirrors what the encoding/xml package would actually produce. A tag like xml:"OrderId,attr" turns the field into an attribute on the parent; xml:"-" drops it; xml:",omitempty" leaves the element out when the value is the zero value; xml:"Items>OrderItem" wraps the slice in an <Items> container with one <OrderItem> per element; xml:",chardata" puts the value as text content. XMLName xml.Name renames the element itself. Pointer fields with nil values are emitted as empty elements only when ,omitempty is absent — exactly the way the standard library behaves.
Scalars are handled the way Go would handle them: float64 prints without scientific notation when it fits, time.Time uses RFC 3339, booleans are lowercase true/false, and int/uint come out unpadded. Nested structs become nested elements. Slices of structs become repeated elements at the same level. Maps are not natively supported by encoding/xml — they get flattened into repeated <Entry><Key/><Value/></Entry> children so the shape is still meaningful. Writing idiomatic Go? The style guide in Effective Go is a good reference for the patterns this tool expects.
How to use it
Three steps. Works the same whether you paste one struct or a whole package file.
Paste your Go (or try the sample)
Drop your Go into the left editor as-is. A single struct declaration, a whole file with imports and multiple types, or a composite literal like order := Order{...} — all work. Click Load Sample for a realistic example first.
You do not need to strip the package line, remove imports, or tidy the file. Paste it the way it comes out of gofmt. Struct tags with backticks are expected.
Hit Convert
Click the green Convert button. The tool reads the Go, honours every xml struct tag, and builds 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 a standards-compliant XML parser will accept. Copy it into your SOAP envelope, config file, test fixture, or API documentation.
When this actually comes in handy
Building SOAP client fixtures
You are talking to a legacy enterprise SOAP API from a Go service. Paste the request struct, get the XML body ready for SoapUI, Postman, or the test suite.
RSS and Atom feeds
A feed struct with Channel, Item, and enclosure fields turns into a working RSS or Atom template — handy for sanity-checking tag layout before wiring up the handler.
Vendor config files
Some SaaS tools still consume XML config (think sitemaps, logging pipelines, legacy ops consoles). Paste the Go config struct, drop the XML straight in.
Keeping docs honest
Generate XML examples for a README or API reference from the actual Go types, so the examples never drift out of sync with the code shipping in main.
Common questions
Can I paste multiple structs at once?
Yes — paste the whole file. The root is detected from the composite literal (e.g. order := Order{...}) when present, or the first struct that references the others. Nested and sibling structs come through as nested elements or separate fragments, so nothing is dropped silently.
Does it honour struct tags like xml:"x,attr", xml:"-", and xml:",omitempty"?
Yes — and all of the common variants. xml:"name" renames the element, xml:"name,attr" emits it as an attribute on the parent, xml:"-" drops the field entirely, xml:",omitempty" skips zero-valued fields, xml:"a>b" wraps the slice in an <a> container with one <b> per element, xml:",chardata" puts the value as element text, and xml:",innerxml" is passed through as raw XML. This matches the behaviour documented in the encoding/xml Marshal reference.
What about the special XMLName field?
A field of type xml.Name named XMLName renames the root element. XMLName xml.Name `xml:"Order"` produces <Order>...</Order>. Without it, the tool uses the struct type name as the root — same default as xml.Marshal.
How does it handle pointers, slices, and maps?
Pointer fields with nil emit an empty element unless ,omitempty is set, in which case they are skipped. Slices of structs become repeated sibling elements (or wrapped in a container when the tag uses the a>b form). Maps are not natively handled by encoding/xml, so the tool emits them as a series of <Entry><Key/><Value/></Entry> children — good enough for most cases, and explicit enough to edit if you need a different shape.
Is my code stored?
Your code is sent to the backend for conversion and is not persisted — we do not log the payload. Standard disclaimer for online tools: if the code is genuinely sensitive, eyeball it before pasting.
What if the struct uses types encoding/xml does not support — channels, funcs, complex?
Those are emitted as empty elements rather than failing the whole conversion, matching what xml.Marshal would do at runtime (it returns an error; the tool keeps going so you still get the rest). If the Go itself has a syntax error, fix the obvious ones first — the parser is forgiving but not a full gc.
Other tools you may need
Go to XML is one piece of the puzzle. These tools pair well with it: