Golang实现XML解析时不创建嵌套结构的Go struct列表方法
Golang实现XML解析时不创建嵌套结构的Go struct列表方法
你好,我遇到了一个问题,需要创建一个Go结构体,以便在反序列化时能够匹配下面的XML结构。问题出在PAYMENTS部分。假设支付结构体有一个名为PMTTYPE和PMTAMOUNT的字段,如何在不创建嵌套结构的情况下,反序列化一个PAYMENTS列表并使它们像下面这样嵌套。
<TOTALS>
<TOTALTAXEXCL>169.49</TOTALTAXEXCL>
<!-- Total of all the items exclusive of Tax-->
<TOTALTAXINCL>200</TOTALTAXINCL>
<!-- Total of all the items inclusive of Tax-->
<DISCOUNT>0.00</DISCOUNT>
</TOTALS>
<PAYMENTS>
<PMTTYPE>CASH</PMTTYPE>
<!-- Mode of Payment can either be CASH, CHEQUE, EMONEY or CCARD if receipt is generated. In this case payment is already received-->
<PMTAMOUNT>200.00</PMTAMOUNT>
<!-- Payment amount-->
<PMTTYPE>INVOICE</PMTTYPE>
<!-- Mode of Payment can only be INVOICE if invoice is generated. In this case payment is not yet received that is why we use Invoice -->
<PMTAMOUNT>200.00</PMTAMOUNT>
<!-- Payment amount-->
</PAYMENTS>
<VATTOTALS>
<VATRATE>A</VATRATE>
<!-- Tax group applicable on the items for VAT items should A and for no VAT items should be C-->
<NETTAMOUNT>169.49</NETTAMOUNT>
<!-- Total of all the items exclusive of Tax-->
<TAXAMOUNT>30.51</TAXAMOUNT>
<!-- Tax amount paid-->
</VATTOTALS>
更多关于Golang实现XML解析时不创建嵌套结构的Go struct列表方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang实现XML解析时不创建嵌套结构的Go struct列表方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢这些尝试。我指的是将一个 Go 结构体转换为类似上面的 XML。期望的结果是让 PMTTYPE 后面跟着 PMTAMOUNT,然后又是 PMTTYPE 后面跟着 PMTAMOUNT,形成一个列表。
我明白了。将代码转换为编码(例如转换为XML或JSON等)的过程称为“序列化”。而反序列化则是当你从XML(或JSON等)转换回结构体(或你正在反序列化的任何其他数据类型)时。
如果你想要生成那个XML的代码,我想你需要的是这个:

如果你除了这两个字段(PMTTYPE 和 PMTAMOUNT)之外还有其他字段,我可能会有不同的想法,但我认为对于仅这两种类型来说,这是最直接的方法。
对于你提到的XML结构,PAYMENTS 部分包含多个交替出现的 PMTTYPE 和 PMTAMOUNT 元素,而不是将它们分组到嵌套结构中。在不创建嵌套结构的情况下,可以通过使用 []string 切片来捕获这些元素,然后在解析后手动配对它们。以下是一个示例实现:
package main
import (
"encoding/xml"
"fmt"
)
type Root struct {
XMLName xml.Name `xml:"Root"`
TOTALS TOTALS `xml:"TOTALS"`
PAYMENTS []string `xml:"PAYMENTS>PMTTYPE,PAYMENTS>PMTAMOUNT"`
VATTOTALS VATTOTALS `xml:"VATTOTALS"`
}
type TOTALS struct {
TOTALTAXEXCL string `xml:"TOTALTAXEXCL"`
TOTALTAXINCL string `xml:"TOTALTAXINCL"`
DISCOUNT string `xml:"DISCOUNT"`
}
type VATTOTALS struct {
VATRATE string `xml:"VATRATE"`
NETTAMOUNT string `xml:"NETTAMOUNT"`
TAXAMOUNT string `xml:"TAXAMOUNT"`
}
func main() {
data := `
<Root>
<TOTALS>
<TOTALTAXEXCL>169.49</TOTALTAXEXCL>
<TOTALTAXINCL>200</TOTALTAXINCL>
<DISCOUNT>0.00</DISCOUNT>
</TOTALS>
<PAYMENTS>
<PMTTYPE>CASH</PMTTYPE>
<PMTAMOUNT>200.00</PMTAMOUNT>
<PMTTYPE>INVOICE</PMTTYPE>
<PMTAMOUNT>200.00</PMTAMOUNT>
</PAYMENTS>
<VATTOTALS>
<VATRATE>A</VATRATE>
<NETTAMOUNT>169.49</NETTAMOUNT>
<TAXAMOUNT>30.51</TAXAMOUNT>
</VATTOTALS>
</Root>`
var root Root
err := xml.Unmarshal([]byte(data), &root)
if err != nil {
fmt.Println("Error:", err)
return
}
// 处理PAYMENTS切片,将PMTTYPE和PMTAMOUNT配对
payments := make([]map[string]string, 0)
for i := 0; i < len(root.PAYMENTS); i += 2 {
if i+1 < len(root.PAYMENTS) {
payment := map[string]string{
"PMTTYPE": root.PAYMENTS[i],
"PMTAMOUNT": root.PAYMENTS[i+1],
}
payments = append(payments, payment)
}
}
fmt.Printf("TOTALS: %+v\n", root.TOTALS)
fmt.Printf("PAYMENTS (paired): %+v\n", payments)
fmt.Printf("VATTOTALS: %+v\n", root.VATTOTALS)
}
在这个示例中,PAYMENTS 字段被定义为 []string,并使用 xml:"PAYMENTS>PMTTYPE,PAYMENTS>PMTAMOUNT" 标签来捕获所有 PMTTYPE 和 PMTAMOUNT 元素。解析后,通过遍历切片并每两个元素配对(假设顺序是 PMTTYPE 后跟 PMTAMOUNT),构建一个 map 列表来表示支付信息。这样避免了创建嵌套结构,同时能处理XML中的交替元素。

