CalcCafe

XML to Go

Paste XML and instantly get Go struct definitions with proper encoding/xml tags, inferred types, and nested types.

Example

Input XML:

<book id="1" inStock="true">
 <title>Go in Action</title>
 <pages>300</pages>
</book>

Generated Go:

type Root struct {
	XMLName xml.Name `xml:"book"`
	ID   int   `xml:"id,attr"`
	InStock bool   `xml:"inStock,attr"`
	Title  string  `xml:"title"`
	Pages  int   `xml:"pages"`
}

How it works

It parses the XML with the browser's DOMParser, walks elements and attributes to infer a type model (string, int, float64, bool, slices for repeated elements, nested structs), then emits exported Go structs with `xml:"..."` tags. The root type is named Root.

Good to know

XML to Go takes a sample XML document and reverse-engineers the Go type definitions you'd need to unmarshal it with the standard encoding/xml package. It reads your XML structure, attributes, and text content, then writes out exported structs with correct xml:"..." struct tags so you can paste them straight into a .go file and call xml.Unmarshal. It's aimed at Go developers consuming a third-party API, config file, RSS/Atom feed, or SOAP-style payload who don't want to hand-write boilerplate field by field.

Reach for it whenever you have a concrete XML example but no published Go schema, or when an external feed changes shape and you need to regenerate types quickly. Because everything runs in the browser, it's also safe for XML that contains internal endpoints, IDs, or other data you wouldn't want to paste into a server-side converter. The generated code always names the top-level type Root and adds an XMLName xml.Name field tagged with the document's root element.

To read the output, match each Go field back to your XML: attributes get a ,attr tag, element text content gets a ,chardata tag (named Value or Text), child elements that appear more than once become slices like []Book, and elements with their own children or attributes are promoted into separate named structs. Types are inferred from the actual values you supply, so the quality of the result depends directly on how representative your sample is.

The main caveat: type inference is sample-driven, so a field that happens to be all-digits in your example becomes int, an empty or missing element falls back to string, and an optional element that simply isn't present in your sample won't appear in the structs at all. Feed it the richest, most complete example you have, then review numeric and boolean fields by hand before trusting them in production.

Frequently asked questions

How are repeated XML elements handled?
When the same child tag appears more than once under a parent, the field is generated as a Go slice (e.g. []Book) so it unmarshals every occurrence correctly with encoding/xml.
How does it decide a field is int, float64, or bool?
It samples the text/attribute values across all matching elements: all-integer values become int, decimal values become float64, true/false become bool, and anything else (or mixed types) falls back to string.
Is my data uploaded anywhere?
No — this tool runs entirely in your browser. Your input never leaves your device and it works offline once loaded.
Is it free?
Yes, completely free with no sign-up and no limits.

People also ask

Does XML to Go support namespaces and prefixed tags?
The generator strips namespace prefixes when naming Go fields (so xmlns and xmlns:* attributes are ignored), and it tags fields with the local element name. It does not emit namespace-qualified xml tags like xml:"ns url element", so if your XML relies on multiple namespaces you may need to add the namespace to the tags manually.
How does it name the Go structs and fields?
The top-level struct is always called Root, and nested elements that have their own children or attributes get struct names derived from their tag. Field names are converted to exported PascalCase, with common initialisms such as ID, URL, API, XML, HTTP, JSON, and UUID kept fully capitalized.
Can I convert the generated structs back into XML?
Yes. The same structs work with xml.Marshal as well as xml.Unmarshal, since encoding/xml uses the struct tags in both directions. Keep in mind that round-tripping may not reproduce the original formatting, attribute order, or namespace declarations exactly.
What happens to an element that has both attributes and text content?
When an element carries attributes and also has text, the text is captured in a separate field tagged xml:",chardata" (named Value when there are no child elements, or Text when children are also present). The attributes become their own fields tagged with ,attr.
Why are some of my values typed as string when they look like numbers?
Type inference samples the actual values across all matching elements; if any value is empty, blank, or doesn't cleanly match an integer, decimal, or true/false pattern, the field falls back to string. Mixed values (for example some integers and some non-numeric text) also resolve to string to stay safe.
Will the structs handle optional or sometimes-missing elements?
Only elements that appear in your sample are included in the output, so an optional element absent from your example won't generate a field. encoding/xml leaves missing elements at their zero value during unmarshal, so adding the field yourself later is usually all that's needed.
Is XML to Go the same as converting XML to JSON?
No. It produces Go source code (struct type definitions), not a data conversion of your document. The goal is to give you the type scaffolding so your Go program can parse XML, rather than transforming the XML into another data format.

Related tools