Golang实现XML解析时不创建嵌套结构的Go struct列表方法

Golang实现XML解析时不创建嵌套结构的Go struct列表方法 你好,我遇到了一个问题,需要创建一个Go结构体,以便在反序列化时能够匹配下面的XML结构。问题出在PAYMENTS部分。假设支付结构体有一个名为PMTTYPEPMTAMOUNT的字段,如何在不创建嵌套结构的情况下,反序列化一个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

4 回复

更多关于Golang实现XML解析时不创建嵌套结构的Go struct列表方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢这些尝试。我指的是将一个 Go 结构体转换为类似上面的 XML。期望的结果是让 PMTTYPE 后面跟着 PMTAMOUNT,然后又是 PMTTYPE 后面跟着 PMTAMOUNT,形成一个列表。

我明白了。将代码转换为编码(例如转换为XML或JSON等)的过程称为“序列化”。而反序列化则是当你从XML(或JSON等)转换回结构体(或你正在反序列化的任何其他数据类型)时。

如果你想要生成那个XML的代码,我想你需要的是这个:

图片

Go Playground - Go编程语言

如果你除了这两个字段(PMTTYPEPMTAMOUNT)之外还有其他字段,我可能会有不同的想法,但我认为对于仅这两种类型来说,这是最直接的方法。

对于你提到的XML结构,PAYMENTS 部分包含多个交替出现的 PMTTYPEPMTAMOUNT 元素,而不是将它们分组到嵌套结构中。在不创建嵌套结构的情况下,可以通过使用 []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" 标签来捕获所有 PMTTYPEPMTAMOUNT 元素。解析后,通过遍历切片并每两个元素配对(假设顺序是 PMTTYPE 后跟 PMTAMOUNT),构建一个 map 列表来表示支付信息。这样避免了创建嵌套结构,同时能处理XML中的交替元素。

回到顶部