Go使用encoding/xml生成无包裹节点的库存数组XML的实现方法
解决方案
Go标准库的encoding/xml包默认会为切片中的每个结构体元素生成独立的外层包裹标签,要实现无外层包裹、直接平铺库存字段的效果,你可以为根结构体实现xml.Marshaler接口,自定义序列化逻辑,手动控制字段输出顺序。
完整修改后代码
package main import ( "encoding/xml" "fmt" "os" "strconv" ) func main() { type InventoryItem struct { ItemName string ItemDescription string } type XMLEnvelop struct { XMLName xml.Name `xml:"root"` Inventory []InventoryItem Records int } // 自定义XML序列化逻辑 func (x XMLEnvelop) MarshalXML(e *xml.Encoder, start xml.StartElement) error { // 写入root开始标签 if err := e.EncodeToken(start); err != nil { return err } // 依次平铺输出每个库存项的Name和Description字段 for _, item := range x.Inventory { if err := e.EncodeElement(item.ItemName, xml.StartElement{Name: xml.Name{Local: "Name"}}); err != nil { return err } if err := e.EncodeElement(item.ItemDescription, xml.StartElement{Name: xml.Name{Local: "Description"}}); err != nil { return err } } // 输出records字段 if err := e.EncodeElement(x.Records, xml.StartElement{Name: xml.Name{Local: "records"}}); err != nil { return err } // 写入root结束标签 return e.EncodeToken(xml.EndElement{Name: start.Name}) } var items []InventoryItem for i := 1; i < 6; i++ { items = append(items, InventoryItem{ ItemName: "Test " + strconv.Itoa(i), ItemDescription: "Description " + strconv.Itoa(i), }) } v := &XMLEnvelop{Records: 1, Inventory: items} output, err := xml.MarshalIndent(v, "", " ") if err != nil { fmt.Printf("error: %v\n", err) } os.Stdout.Write(output) }
输出结果
<root> <Name>Test 1</Name> <Description>Description 1</Description> <Name>Test 2</Name> <Description>Description 2</Description> <Name>Test 3</Name> <Description>Description 3</Description> <Name>Test 4</Name> <Description>Description 4</Description> <Name>Test 5</Name> <Description>Description 5</Description> <records>1</records> </root>
完全匹配客户期望的格式要求。
内容的提问来源于stack exchange,提问作者monkeymynd
相关产品推荐
相关产品推荐

