Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xml namespace prefix issue at go

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 ?
like image 780
Siddhanta Rath Avatar asked Feb 04 '18 15:02

Siddhanta Rath


People also ask

How do I add namespace prefix to XML element?

When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".

What is an XML namespace prefix used for?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.

What is prefix in XML?

An XML namespace prefix is an abbreviation for the full XML namespace. Because namespaces are meant to differentiate unqualified XML names, it's better that the namespaces themselves be sufficiently long to create a lexically distinct new name when prepended to the unqualified names.

What is the default XML namespace?

When you use multiple namespaces in an XML document, you can define one namespace as the default namespace to create a cleaner looking document. The default namespace is declared in the root element and applies to all unqualified elements in the document. Default namespaces apply to elements only, not to attributes.


1 Answers

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
}
like image 152
ttomalak Avatar answered Sep 19 '22 08:09

ttomalak