Code Generators
XML to Go Converter
Paste an XML sample, get typed Go models — names, nesting and nullability inferred for you.
In short
Convert XML to Go online: paste a sample and generate typed Go models with serialization helpers — powered by quicktype, in your browser.
By NaveenKumar T · Updated
- Typed models from one sample
- Nested objects become types
- Nullability inferred
Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →
Example
Example: XML order payload to Go
The same order as XML, with data split between attributes (id, status, paid, sku, qty, price) and element text (name, email, total) — the split that decides which Go fields are typed as numbers and which stay strings. The right-hand side is the exact output of this tool.
<order id="ord_9F2KX" status="processing" paid="true">
<customer>
<name>Ada Lovelace</name>
<email>ada@example.com</email>
</customer>
<items>
<item sku="KB-75" qty="1" price="149.99"/>
<item sku="MS-12" qty="2" price="39.5"/>
</items>
<total>228.99</total>
</order>// Code generated from JSON Schema using quicktype. DO NOT EDIT.
// To parse and unparse this JSON data, add this code to your project and do:
//
// root, err := UnmarshalRoot(bytes)
// bytes, err = root.Marshal()
package main
import "encoding/json"
func UnmarshalRoot(data []byte) (Root, error) {
var r Root
err := json.Unmarshal(data, &r)
return r, err
}
func (r *Root) Marshal() ([]byte, error) {
return json.Marshal(r)
}
type Root struct {
Order Order `json:"order"`
}
type Order struct {
Customer Customer `json:"customer"`
Items Items `json:"items"`
Total float64 `json:"total"`
ID string `json:"id"`
Status string `json:"status"`
Paid string `json:"paid"`
}
type Customer struct {
Name string `json:"name"`
Email string `json:"email"`
}
type Items struct {
Item []Item `json:"item"`
}
type Item struct {
Sku string `json:"sku"`
Qty string `json:"qty"`
Price string `json:"price"`
}
Compare "total" (element text, typed float64) with "price" and "qty" (attributes, kept as string). The root <order> element became a nested Order type under Root.
Learn more
From XML sample to Go types
Hand-writing model classes from an XML payload means deciding, field by field, which parser reads which node — this page automates that decision. quicktype first parses your document into a data model, attributes included, then runs the same type inference it uses for JSON against the result.
Every number is float64, and the sample's 149.99 hides the consequence: an integer ID above 2^53 — 9,007,199,254,740,993, say — cannot be represented exactly and comes back rounded. If the API sends 64-bit integer IDs, change those fields to int64 (or json.Number) before the first production payload. Key matching on unmarshal is case-insensitive but the json tag is exact on marshal, so trust the tags over the field names.
How XML elements and attributes become Go types
The XML is parsed into a data model before inference (attributes included, text nodes named "text"), so the root element becomes a nested type: <order> is a field of type Order on the top-level Root rather than the top level itself. Child elements become fields, and repeated elements — the two <item> siblings — are collected into []Item under an Items wrapper type that mirrors the <items> container.
Attributes and element text are typed differently, and this matters: element text is type-inferred, so <total>228.99</total> becomes float64, while attribute values are kept as they were written — qty="1" and price="149.99" stay string in Go. Prefer element text for numeric data you want typed, or cast attribute values after decoding. One more trap: a single <item> would not be recognized as a list, so make sure repeated elements appear at least twice in the sample.
Reading the XML in Go with the generated structs
encoding/xml ignores json tags entirely: it matches element names against field names and reads attributes only into fields tagged with ,attr — so id, status, sku, qty and price would all come back empty from these structs. Convert the document to JSON first instead. mxj (or any xml2json helper) turns the XML into a map that marshals into exactly the shape UnmarshalRoot expects; call PrependAttrWithHyphen(false) before parsing so attribute names stay as the generator saw them, without a leading hyphen.
import (
"encoding/json"
"github.com/clbanning/mxj/v2"
)
mxj.PrependAttrWithHyphen(false) // keep attribute names as written
m, err := mxj.NewMapXml([]byte(xmlText)) // map[string]interface{}
b, err := json.Marshal(m) // {"order":{ … }}
root, err := UnmarshalRoot(b) // (error handling elided)
fmt.Println(root.Order.Items.Item[0].Sku) // KB-75Help
Frequently asked questions
Everything you need to know about the XML to Go.
01How do I generate Go classes from XML?
Paste an XML document and press Convert. It is first parsed into a data model — attributes included — then typed: the root element becomes a nested type, repeated elements become []Item, and the result downloads as Root.go.
02Why do the structs return empty fields when I use encoding/xml?
encoding/xml ignores json tags and reads attributes only from fields tagged ,attr, so id, status, sku, qty and price come back empty. Convert the document to JSON first (mxj with PrependAttrWithHyphen(false)) and unmarshal that with the generated UnmarshalRoot.
03Why are qty and price strings in Go?
XML attributes reach the generator as strings and Go keeps them that way — only element text such as total is type-inferred to float64. Convert with strconv after decoding, or move numeric data into element text in the source XML.
04Do attribute values stay strings all the way through, or does something type them along the way?
They stay strings the whole way: mxj's XML-to-map conversion has no type inference, so qty and price arrive as Go strings exactly as the struct tags declare, and nothing downstream promotes them to numbers. Convert with strconv.Atoi or strconv.ParseFloat after unmarshalling if the values need to be numeric in your code.
Keep working