xml namespace prefix issue at go
Asked Answered
L

2

14

marshalling and unmarshalling are not working properly with xml namespace prefix

go version 1.9.2 See below code:

package main

import (

    "fmt"
    "encoding/xml")

type DeviceId struct {
    XMLName      xml.Name `xml:"DeviceId"`
    Manufacturer string   `xml:"Manufacturer"`
    OUI          string   `xml:"OUI"`
    ProductClass string   `xml:"ProductClass"`
    SerialNumber string   `xml:"SerialNumber"`
}

type CwmpInform struct {
    XMLName xml.Name `xml:"cwmp:Inform"`
    DeviceId     DeviceId      
}


func main() {
    rq := new(CwmpInform)
    data := `<cwmp:Inform>
                <DeviceId>
                <Manufacturer></Manufacturer>
                <OUI>48BF74</OUI>
                <ProductClass>FAP</ProductClass>
                <SerialNumber>1202000042177AP0008</SerialNumber>
                </DeviceId>
              </cwmp:Inform>`

    xml.Unmarshal([]byte (data), rq)
    fmt.Printf("Unmarshelled Content:%v", rq)
    output, err := xml.MarshalIndent(rq,"  ", "  ")
    if err != nil{
    fmt.Printf("error : %v", err)
    }
    fmt.Printf("Marshelled Content: %s\n", string(output))
}

Output of above program with proper marshalled Content and empty Marshelled content :

Unmarshelled Content:&{{ } {{ }    }}
 Marshelled Content: 
  <cwmp:Inform>
    <DeviceId>
      <Manufacturer></Manufacturer>
      <OUI></OUI>
      <ProductClass></ProductClass>
      <SerialNumber></SerialNumber>
    </DeviceId>
  </cwmp:Inform>

but when i change the struct's xml tag from xml:"cwmp:Inform" to xml:"cwmp Inform", then Unmarshelling happens properly, but i get below output for Marshelled content :

<Inform xmlns="cwmp">
    <DeviceId>
      <Manufacturer></Manufacturer>
      <OUI>48BF74</OUI>
      <ProductClass>FAP</ProductClass>
      <SerialNumber>1202000042177AP0008</SerialNumber>
    </DeviceId>
  </Inform>

Instead of getting <cwmp:Inform>, I am getting <Inform xmlns="cwmp">

  • Is there any work around to correct the marshelled content ? Is it a go language Issue ?
Liddle answered 4/2, 2018 at 15:16 Comment(0)
A
14

Is probably the same issue here

https://github.com/golang/go/issues/9519

To fix that you need to use two structs, one for Unmarshalling and second to Marshalling data

type CwmpInformUnmarshal struct {
    XMLName  xml.Name `xml:"Inform"`
    DeviceId DeviceId
}

type CwmpInformMarshall struct {
    XMLName  xml.Name `xml:"cwmp:Inform"`
    DeviceId DeviceId
}
Anaglyph answered 4/2, 2018 at 15:46 Comment(6)
Thank you for your answer, but when CwmpInformUnmarshal will be a part of a parent struct and used to Unmarshal against below xml content : <Body> <cwmp:Inform> <DeviceId> <Manufacturer></Manufacturer> <OUI>48BF74</OUI> <ProductClass>FAP</ProductClass> <SerialNumber>1202000042177AP0008</SerialNumber> </DeviceId> </cwmp:Inform> <Body> give output as empty structs :(Liddle
Yeah it's seems that there is something wrong with tags, but when you add Inform to xml.Name it unmarsall it properly. But still you will need to create another BodyM/BodyU struct for this.Anaglyph
Thanks a ton :) @AnaglyphLiddle
Thanks for the workaround it does seem to work but I also ran into the empty structs problem. Can you please explain what you mean by create another BodyM/BodyU struct @AnaglyphPilau
hello @hoos, I'm happy that this answer helped you to resolve issue. It was some time ago, but if I remember correctly by this I mean thatm for parent struct to properly handle Unmarshal/Marshal you also need to create seperate structs.Anaglyph
Thanks @Anaglyph for the swift response! You are right I needed entirely separate structures for marshalling and unmarshalling.Pilau
B
0

I have put namespace prefixes and used https://github.com/nbio/xml as unmarshaller and built-in xml.Marshaller. It solved for me.

Beltz answered 14/8 at 12:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.