Get new struct from struct

Hi,

I am trying to implement a struct that will pass one of several structs to a function that will convert the data to XML. A simple working example of passing a string to xml.Unmarshal() works as expected:

https://play.golang.org/p/61KOu3bNoQj

However if I try to create a struct that will “pass” the struct to the function the result is an empty struct and incorrect XML:

https://play.golang.org/p/Fb6_krjfkLa

I’m sure I’m just missing something simple, but with my limited knowledge of Go I seem to be having a problem figuring this out.

Thanks,

Rob

2 Likes

As DataStruct is an empty nterface i guess you have to cast to a specifi type. For example
data := x.DataStruct.(XmlData)
to be able to parse the xml string…

2 Likes

The problem is that I won’t know the specific type. BTW that does work, but…what’s the best way to get the underlying type when I won’t know that?

2 Likes

Maybe

t := reflect.TypeOf(x.DataStruct)
switch t.Kind() {
   case reflect.Struct:
     fmt.Printf("%v\n", t)
     data := x.DataStruct.(XmlData)
     xml.Unmarshal([]byte(rawXml),&data)
     fmt.Printf("The value of data is: %v\n",data)
     out, _ := xml.Marshal(data)
     fmt.Printf("The value of out is: %s\n",string(out))
}
2 Likes

Unfortunately I will be needing to handle literally dozens of structs so that approach would be impractical. Anything that would involve a type switch would become unmanageable.

Rob

2 Likes

I gave up…Everything I tried (and I’m sure I missed something) to get the xml.Unmarshal() to work correctly with an interface{} failed. And I couldn’t figure out an easy way to get the struct. So, at least for now, I’m using a type switch and instantiating the struct directly without reflect.

Thanks for the help,

Rob

2 Likes

try something like

data, ok := x.DataStruct.(XmlData)

and if it is ok than unmarshal it

2 Likes

Hi,

As I mentioned before, while that works, in my actual application I won’t know the data type coming in, and I will be using potentially dozens of types. So if I end up having to do a type switch anyway, I might as well not bother with defining the DataStruct as an interface.

Thanks,

Rob

3 Likes

I can’t really help with determining which struct to use because you pretty much have to do some kind of switch statement. Perhaps, you could add a required field such as tag which includes the xml’s type but you’d need a dummy struct to load that in. As for sending the struct to another function you’re going to want to create an interface that all the structs complete. Such as getName xml.Name and getValue []string that way the receiving function can always get the name, and loop through the values. I’m not sure what the ultimate goal is of what you’re trying to do but here is some code that may help spark something new. https://play.golang.org/p/pyrpm0RHSNb

EDIT: I came up with a better way than using a switch statement. You can use a map where the key is the tag field and the value is the struct that should be used to unmarshal. So something like map[string]XmlInterface. Doing it this way means you only need to do one check - an error check to see if the struct was found.

2 Likes

Actually, I realized that all the xml.Unmarshal() and xml.Marshal() end up doing is first converting the XML string into a struct and then converting the struct into a byte slice. So, technically, after removing the extra spaces between the tags (I format the XML string with newlines and tabs to make it easier to read) all I really needed to do was convert the string to a byte slice and voila…So I’m no longer using xml.(Unm/M)arshal.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.