doupingpeng7567 2018-12-28 06:18
浏览 97
已采纳

Go XML编码问题

I need to produce the following xml :

<AccessControlList>
    <Grant>
        <Grantee
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
            <ID>xxxx-xx</ID>
            <DisplayName>rahul.khan</DisplayName>
        </Grantee>
        <Permission>FULL_CONTROL</Permission>
    </Grant>
</AccessControlList>

My struct is defined like this :

type Grantee struct {
Xmlns_xsi   string `xml:"xmlns xsi,attr,omitempty"`
Xsi_type    string `xml:"http://www.w3.org/2001/XMLSchema-instance type,attr,omitempty"`
ID          string `xml:",omitempty"`
DisplayName string `xml:",omitempty"`

}

However when i marshall this structure the resulting xml document that is produced looks like this :

<AccessControlList>
    <Grant>
        <Grantee
            xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="CanonicalUser">
            <ID>xxxx-xx</ID>
            <DisplayName>rahul.khan</DisplayName>
        </Grantee>
        <Permission>FULL_CONTROL</Permission>
    </Grant>
</AccessControlList>

As a result, when the doc is unmarshalled, the type field doesn't seem to be parsed by the aws-go-sdk.

For e.g this is the unmarhsalled output that i need to get

Grantee: {
    DisplayName: "rahul.khan",
    ID: "xxxx-xx",
    Type: "CanonicalUser"
  },
  Permission: "FULL_CONTROL"
}

Instead what I get is this :

  Grantee: {
    DisplayName: "rahul.khan",
    ID: "xxxx-xx"
  },
  Permission: "FULL_CONTROL"
}

The Type attribute seems to be missing from the unmarshalled output. The only difference that I see in the xml document produced by my code and from aws is this line

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser" v/s

xmlns:XMLSchema-instance="http://www.w3.org/2001/XMLSchema-instance" XMLSchema-instance:type="CanonicalUser"

Appreciate if someone can help me understand how to fix this issue ?

  • 写回答

1条回答 默认 最新

  • 普通网友 2018-12-28 19:32
    关注

    This struct Marshals to the XML you need, using just endcoding/xml.Marshal():

    type Grantee struct {
        Xmlns_xsi   string `xml:"xmlns:xsi,attr,omitempty"`  //set namespace prefix explicitly
        Xsi_type    string `xml:"xsi:type,attr,omitempty"`   //set namespace:attr  explicitly
        ID          string `xml:",omitempty"`
        DisplayName string `xml:",omitempty"`
    }
    
    g := Grantee{
        DisplayName: "rahul.khan",
        ID:          "xxxx-xx",
        Xsi_type:    "CanonicalUser",
        Xmlns_xsi:   "http://www.w3.org/2001/XMLSchema-instance", // set namespace URI as the value of the field
    }
    
    gm, err := xml.MarshalIndent(g, "", "  ")
    if err != nil {
        fmt.Printf("error: %v", err)
        return
    }
    
    fmt.Printf("%+s
    ", gm)
    
    //<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
    //  <ID>xxxx-xx</ID>
    //  <DisplayName>rahul.khan</DisplayName>
    //</Grantee>
    

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

    Notice that the xmlns:xsi and xsi:type are just set as explicit attribute names, including the colons. As you found, if you leave a space between the namespace and attribute name, encoding/xml makes changes in an attempt to clean up the namespaces in the output (like using the final part of a namespace-URL as the namespace prefix: e.g. XMLSchema-instance).

    I recognize that this XML may not Unmarshal into your Go struct as you would like (as discussed in many golang issues, such as the one referenced by @Adrian in the comment to your question). But, if you're submitting to the S3 Rest API to change the ACL, it looks like this xml will be correct). The aws-go-sdk appears to use their own function to deserialise XML, so give it a try.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码