1

I am trying to use interface{} to Marshal and UnMarshal my xml in golang. The reason is that as in calling a soap server my soap envelope, header are same but i want to pass the different soap function by passing different structs. I have made a sample code in playground(not related to soap). I am able to marshal the xml with interface{} but unable to unmarshal.

Here is link Play Ground

Please tell me what i am doing wrong ?

user
  • 2,694
  • 6
  • 24
  • 25
  • 1
    that's really odd. I even changed your code to use the same methods of the json encoder, the rest of the code was identical - and it worked just fine. you can see my version here - it's identical apart from the marshal/unmarshal calls http://play.golang.org/p/rX-lOz4toV – Not_a_Golfer May 14 '14 at 12:46
  • @Not_a_Golfer Yes it is. Can you suggest me some other way to doing it. As i have explained in my question i need for sending soap xml(WSDL). In which i will make a common soap Envelope struct and make a interface{} in it and for different web services i will pass there structure(Marshal/Unmarshal) during send and receive – user May 14 '14 at 13:05
  • Maybe try using http://golang.org/pkg/encoding/xml/#Decoder.DecodeElement ? it will be more complicated, but seems like it might work. – Not_a_Golfer May 14 '14 at 13:09
  • 1
    here's an answer suggesting something similar, with actual code: http://stackoverflow.com/a/12258671/1239701 – Not_a_Golfer May 14 '14 at 13:11
  • @Not_a_Golfer i have seen that example and i will try the same with it. – user May 14 '14 at 13:58
  • @Not_a_Golfer I have done it with decoder also http://play.golang.org/p/DC2Pexw8Zl But still it is not working i think there is bug in xml package – user May 14 '14 at 14:39
  • 2
    Conceptually, if `Msg` is an `interface{}` I'm not sure how `xml` "knows" to put a `Child` in there instead of some other type--it works if the type is statically `*Child` (see http://play.golang.org/p/ZoF5IumWwL). That's probably where `Decode`/`DecodeElement` would have to come in: they can peek at the XML and figure out what to create based on what kind of tag it sees. But agree that decoding XML into a type structure not know ahead of time is going to be tricky. – twotwotwo May 14 '14 at 20:04
  • 1
    Not_a_Golfer's JSON example works because the JSON decoder picks a default type like `map[string]interface{}` or the like when it has to decode into an interface{}. The xml decoder's rules are...tricky: http://golang.org/pkg/encoding/xml/#Unmarshal – twotwotwo May 14 '14 at 20:17
  • (Something hacky that might technically work: use a `*Child` pointer like in the last Playground lik, and make `Child` contain *all* the different included in any of the reply types. That sort of shifts your whole app structure around for the sake of easier XML decoding, though, and I don't find it a satisfying solution.) – twotwotwo May 14 '14 at 20:23

1 Answers1

1

You can't unmarshal to an empty interface since the empty interface doesn't have any exported fields to map the xml keys/values to. If you want share your same code to "dynamically" handle the message differently, you should store it in a string or byte array (a byte array is recommended in this case). You then process the data based on your needs.

http://play.golang.org/p/sPq0ZfAcU7

Matt Aimonetti
  • 1,112
  • 1
  • 10
  • 11