Say I have following block of xml data.
<Result>
<person>
<name>Dave</name>
</person>
<id>
<number>1234</number>
</id>
</Result>
and I want to restructure it to following.
<Restructured>
<Person>Dave</Person>
<Id>1234</Id>
</Restructured>
But only using one struct to do it. Is it possible?
Attaching code below.
package main
import (
"encoding/xml"
"fmt"
"os"
)
type Result struct {
Person string `xml:"person>name"`
Id int `xml:"id>number"`
}
type Restructured struct {
Person string
Id int
}
const data = `
<Result>
<person>
<name>Dave</name>
</person>
<id>
<number>1234</number>
</id>
</Result>`
func main() {
v := Result{}
err := xml.Unmarshal([]byte(data), &v)
if err != nil {
fmt.Printf("error: %v", err)
return
}
newV := Restructured{Person: v.Person, Id: v.Id}
output, err := xml.MarshalIndent(newV, " ", " ")
if err != nil {
fmt.Printf("error: %v
", err)
}
os.Stdout.Write(output)
}
I don't want to do it like this, allocating a new type of struct("newV") and copying field by field. Is there any way to marshal automatically with different xml tags using original struct "v"?
Using a second struct is the most convenient way I see. If you don't want to make it exported, you can actually hide the other type inside your MarshalXML
:
func (r *Result) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
type Restructured struct {
Person string
ID int `xml:"Id"`
}
rr := &Restructured{Person: r.Person, ID: r.ID}
return enc.Encode(rr)
}
Playground: http://play.golang.org/p/jZU2Jg0ZRZ.