英文:
golang: Omit name of struct in xml.Marshal
问题
尝试为XML获取特定的输出:
<RESPONSE>
    <DELIMITER value="09"></DELIMITER>
    <COLUMNS>Id	FirstName	LastName	Company	Initials</COLUMNS>
     <DATA>87734	Some Guy	Keller Williams Realty Empire	</DATA>
     <DATA>87739	Another Guy	Level Group, Inc.	</DATA>
     <DATA>87741	Some Gal	Kian Realty NYC, LLC	</DATA>
</RESPONSE>
而我得到的是:
<RESPONSE>
 <compactData>
        <DELIMITER value="09"></DELIMITER>
        <COLUMNS>Id	FirstName	LastName	Company	Initials</COLUMNS>
        <DATA>87734	Some Guy	Keller Williams Realty Empire	</DATA>
        <DATA>87739	Another Guy	Level Group, Inc.	</DATA>
        <DATA>87741	Some Gal	Kian Realty NYC, LLC	</DATA>
 </compactData>
</RESPONSE>
我试图完全不输出 <compactData> 标签。(其他都没问题)
我要编组的结构如下:
type delimiter struct {
	Value string `xml:"value,attr"`
}
type innerData struct {
	Data string `xml:",innerxml"`
}
type compactData struct {
	Delimiter delimiter    `xml:"DELIMITER"`
	Columns   *innerData   `xml:"COLUMNS"`
	Records   []*innerData `xml:"DATA"`
}
我尝试过添加
XMLName   xml.Name
或者
XMLName   xml.Name `xml:""`
但都没有效果- xml.MarshalIndent 只是说 '是的,看起来像垃圾,取代结构名'。
我觉得我可能只需要稍微重新组织一下结构,但是对于所需的神奇结构我感到困惑。
谢谢!
编辑:<RESPONSE> 标签是在发送 http.reponse 之后添加的,完成此格式化后,尝试保持与 JSON 和 XML 编码相同的签名...
像这样:
func createResponse(obj interface{}, format string) (*Response, error) {
	var data []byte
	var f func(interface{}, string, string) ([]byte, error)
	switch format {
	case FORMAT_JSON:
		f = json.MarshalIndent
	case FORMAT_COMPACT:
		f = compact.MarshalIndent
	default:
		f = xml.MarshalIndent
	}
	data, err := f(obj, " ", "    ")
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return &Response{Data: string(data)}, nil
}
英文:
Trying to get a particular output for XML:
<RESPONSE>
    <DELIMITER value="09"></DELIMITER>
    <COLUMNS>Id	FirstName	LastName	Company	Initials</COLUMNS>
     <DATA>87734	Some Guy	Keller Williams Realty Empire	</DATA>
     <DATA>87739	Another Guy	Level Group, Inc.	</DATA>
     <DATA>87741	Some Gal	Kian Realty NYC, LLC	</DATA>
</RESPONSE> 
instead I am getting:
<RESPONSE>
 <compactData>
        <DELIMITER value="09"></DELIMITER>
        <COLUMNS>Id	FirstName	LastName	Company	Initials</COLUMNS>
        <DATA>87734	Some Guy	Keller Williams Realty Empire	</DATA>
        <DATA>87739	Another Guy	Level Group, Inc.	</DATA>
        <DATA>87741	Some Gal	Kian Realty NYC, LLC	</DATA>
 </compactData>
</RESPONSE> 
I am trying not to output the <compactData> tag at all. (everything else is a-ok)
my struct that I am marshal-ing looks like this:
type delimiter struct {
	Value string `xml:"value,attr"`
}
type innerData struct {
	Data string `xml:",innerxml"`
}
type compactData struct {
	Delimiter delimiter    `xml:"DELIMITER"`
	Columns   *innerData   `xml:"COLUMNS"`
	Records   []*innerData `xml:"DATA"`
}
I have tried putting in
XMLName   xml.Name
or
XMLName   xml.Name `xml:""`
to no avail- the xml.MarshalIndent just says 'yeah that looks like crap taking the struct name instead'.
I feel as though I just may need to reorganize the struct a bit, but I am stumped as to the magic structure needed.
Thanks!
Edit: the <RESPONSE> tag is added as the http.reponse is sent, after this formatting is done, trying to keep this signature the same as JSON and XML encoding...
like so:
func createResponse(obj interface{}, format string) (*Response, error) {
	var data []byte
	var f func(interface{}, string, string) ([]byte, error)
	switch format {
	case FORMAT_JSON:
		f = json.MarshalIndent
	case FORMAT_COMPACT:
		f = compact.MarshalIndent
	default:
		f = xml.MarshalIndent
	}
	data, err := f(obj, " ", "    ")
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return &Response{Data: string(data)}, nil
}
答案1
得分: 4
如果RESPONSE是另一个struct,你可以将compactData嵌入其中,并让encoding/xml按照你的要求进行处理。
type RESPONSE struct {
    compactData
}
https://play.golang.org/p/hN1hDY7pnV
更新:
实际上,如果我理解正确的话,你可以通过实现xml.Marshaler接口来实现你想要的效果。例如,可以像这样实现:https://play.golang.org/p/Uwm0pP1pWh。
英文:
If RESPONSE is another struct you could embed compactData in it and let encoding/xml do what you want.
type RESPONSE struct {
	compactData
}
https://play.golang.org/p/hN1hDY7pnV
Update:
Actually you can do what you want, if I understood you correctly, by implementing the xml.Marshaler interface. E.g. something like this: https://play.golang.org/p/Uwm0pP1pWh.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论