Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshalling XML Go XMLName + xmlns

I am trying to achive the following XML output

<?xml version="1.0" encoding="UTF-8"?>

<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2012-12-12/">
   <Name>DNS domain name</Name>
   <CallerReference>unique description</CallerReference>
   <HostedZoneConfig>
      <Comment>optional comment</Comment>
   </HostedZoneConfig>
</CreateHostedZoneRequest>

I have the following which outputs XML that is very close however I have been unable to encode into CreateHostedZoneRequest

xmlns="https://route53.amazonaws.com/doc/2012-12-12/

package main

import "fmt"
import "encoding/xml"

type ZoneRequest struct {
  Name            string
  CallerReference string
  Comment         string `xml:"HostedZoneConfig>Comment"`
}

var zoneRequest = ZoneRequest{
  Name:            "DNS domain name",
  CallerReference: "unique description",
  Comment:         "optional comment",
}

func main() {
  tmp, _ := createHostedZoneXML(zoneRequest)
  fmt.Println(tmp)
}

func createHostedZoneXML(zoneRequest ZoneRequest) (response string, err error) {
  tmp := struct {
    ZoneRequest
    XMLName struct{} `xml:"CreateHostedZoneRequest"`
  }{ZoneRequest: zoneRequest}

  byteXML, err := xml.MarshalIndent(tmp, "", `   `)
  if err != nil {
    return "", err
  }
  response = xml.Header + string(byteXML)
  return
}

http://play.golang.org/p/pyK76VPD5-

How can I encode xmlns into the CreateHostedZoneRequest?

like image 537
Karl Entwistle Avatar asked Apr 24 '13 21:04

Karl Entwistle


2 Answers

I had a similar question. The docs for the Unmarshal method (http://golang.org/pkg/encoding/xml/#Unmarshal) have:

If the XMLName field has an associated tag of the form "name" or "namespace-URL name", the XML element must have the given name (and, optionally, name space) or else Unmarshal returns an error.

Using "namespace-URL name" in the struct tag:

type ZoneRequest struct {
    XMLName  xml.Name `xml:"https://route53.amazonaws.com/doc/2012-12-12/ CreateHostedZoneRequest"`
}

Should produce:

<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2012-12-12/">
like image 50
burr Avatar answered Nov 02 '22 22:11

burr


You can do this, which possibly isn't the most elegant solution, but seems to work

Playground link

type ZoneRequest struct {
    Name            string
    CallerReference string
    Comment         string `xml:"HostedZoneConfig>Comment"`
    Xmlns           string `xml:"xmlns,attr"`
}

var zoneRequest = ZoneRequest{
    Name:            "DNS domain name",
    CallerReference: "unique description",
    Comment:         "optional comment",
    Xmlns:           "https://route53.amazonaws.com/doc/2012-12-12/",
}

Producing

<?xml version="1.0" encoding="UTF-8"?>

<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2012-12-12/">
   <Name>DNS domain name</Name>
   <CallerReference>unique description</CallerReference>
   <HostedZoneConfig>
      <Comment>optional comment</Comment>
   </HostedZoneConfig>
</CreateHostedZoneRequest>
like image 6
Nick Craig-Wood Avatar answered Nov 02 '22 20:11

Nick Craig-Wood