I am consuming a REST API that returns XML and am trying to Unmarshal the XML and am having issues that appear that the omitempty
is not working. Here is an example of a working XML file:
<?xml version='1.0' encoding='UTF-8'?>
<customer uri="/api/customers/339/" id="339">
<name>
<first>Firstname</first>
<last>Lastname</last>
</name>
<email>myemail@example.com</email>
<billing>
<address>
<address1>123 Main St.</address123>
<address2></address2>
<city>Nowhere</city>
<state>IA</state>
<country>USA</country>
<zip>12345</zip>
</address>
</billing>
</customer>
Here is an example of a "bad" record
<?xml version='1.0' encoding='UTF-8'?>
<customer uri="/api/customers/6848/" id="6848">
<name>
<first>Firstname</first>
<last>Lastname</last>
</name>
<email/>
<billing/>
</customer>
Now I have my structs set up like the following:
type Customer struct {
ID int `xml:"id,attr"`
Name *Name `xml:"name,omitempty"`
Billing *Billing `xml:"billing,omitempty"`
}
type Billing struct {
Address *Address `xml:"address,omitempty"`
}
type Address struct {
address_1 string `xml:",omitempty"`
address_2 string `xml:",omitempty"`
city string `xml:",omitempty"`
postal string `xml:",omitempty"`
country string `xml:",omitempty"`
}
type Name struct {
first, last string
}
Reading through all of the records it works when the XML follows the pattern of the first example <billing></billing>
but when it hits a record that has something like <billing/>
it throws the following error: panic: runtime error: invalid memory address or nil pointer dereference
Can someone help me figure out what's going on and how to resolve it?
You're probably misunderstanding what ,omitempty
means. It takes effect when marshalling data, only. If you unmarshal <billing/>
onto a pointer field with ,omitempty
, it will still initialize the field. Then, since the XML element is empty, the fields of Billing
itself won't be set. In practice, if you assume that customer.Billing != nil
means customer.Billing.Address != nil
, you'll get the observed panic.