2 回复
我移除了所有 soap:、xmlns:、in: 前缀,然后它似乎可以工作了 → 似乎可以工作:Go Playground - The Go Programming Language
免责声明:我不熟悉 XML 解组,因此此解决方案可能仅在此特定上下文中偶然有效。
更多关于Golang如何将XML反序列化为结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go语言中,可以使用标准库的encoding/xml包将XML反序列化为结构体。以下是具体实现方法:
1. 基本反序列化
package main
import (
"encoding/xml"
"fmt"
"strings"
)
type Person struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Age int `xml:"age"`
Email string `xml:"email"`
}
func main() {
xmlData := `
<person>
<name>张三</name>
<age>30</age>
<email>zhangsan@example.com</email>
</person>`
var person Person
err := xml.Unmarshal([]byte(xmlData), &person)
if err != nil {
fmt.Println("解析错误:", err)
return
}
fmt.Printf("姓名: %s\n", person.Name)
fmt.Printf("年龄: %d\n", person.Age)
fmt.Printf("邮箱: %s\n", person.Email)
}
2. 处理嵌套结构
type Address struct {
City string `xml:"city"`
Street string `xml:"street"`
ZipCode string `xml:"zipcode"`
}
type Employee struct {
XMLName xml.Name `xml:"employee"`
ID int `xml:"id,attr"`
Name string `xml:"name"`
Dept string `xml:"department"`
Address Address `xml:"address"`
}
func main() {
xmlData := `
<employee id="1001">
<name>李四</name>
<department>技术部</department>
<address>
<city>北京</city>
<street>中关村大街</street>
<zipcode>100080</zipcode>
</address>
</employee>`
var emp Employee
err := xml.Unmarshal([]byte(xmlData), &emp)
if err != nil {
fmt.Println("解析错误:", err)
return
}
fmt.Printf("ID: %d\n", emp.ID)
fmt.Printf("姓名: %s\n", emp.Name)
fmt.Printf("地址: %s %s %s\n", emp.Address.City, emp.Address.Street, emp.Address.ZipCode)
}
3. 处理数组/切片
type Company struct {
XMLName xml.Name `xml:"company"`
Employees []Employee `xml:"employees>employee"`
}
func main() {
xmlData := `
<company>
<employees>
<employee id="1001">
<name>王五</name>
<department>研发部</department>
</employee>
<employee id="1002">
<name>赵六</name>
<department>市场部</department>
</employee>
</employees>
</company>`
var company Company
err := xml.Unmarshal([]byte(xmlData), &company)
if err != nil {
fmt.Println("解析错误:", err)
return
}
for _, emp := range company.Employees {
fmt.Printf("员工ID: %d, 姓名: %s, 部门: %s\n", emp.ID, emp.Name, emp.Dept)
}
}
4. 使用xml.Unmarshal的完整示例
package main
import (
"encoding/xml"
"fmt"
"io"
"os"
)
type Book struct {
XMLName xml.Name `xml:"book"`
ISBN string `xml:"isbn,attr"`
Title string `xml:"title"`
Author string `xml:"author"`
Price float64 `xml:"price"`
Description string `xml:"description"`
Categories []string `xml:"categories>category"`
}
func main() {
// 从字符串解析
xmlStr := `
<book isbn="978-7-121-12345-6">
<title>Go语言编程实战</title>
<author>Go专家</author>
<price>89.90</price>
<description>深入讲解Go语言高级特性</description>
<categories>
<category>编程</category>
<category>计算机</category>
<category>Go语言</category>
</categories>
</book>`
var book Book
err := xml.Unmarshal([]byte(xmlStr), &book)
if err != nil {
fmt.Println("解析错误:", err)
return
}
fmt.Printf("ISBN: %s\n", book.ISBN)
fmt.Printf("书名: %s\n", book.Title)
fmt.Printf("价格: %.2f\n", book.Price)
fmt.Printf("分类: %v\n", book.Categories)
// 从文件解析
file, err := os.Open("book.xml")
if err != nil {
fmt.Println("打开文件错误:", err)
return
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
fmt.Println("读取文件错误:", err)
return
}
var bookFromFile Book
err = xml.Unmarshal(data, &bookFromFile)
if err != nil {
fmt.Println("解析文件错误:", err)
return
}
}
5. 处理CDATA和命名空间
type Article struct {
XMLName xml.Name `xml:"article"`
ID string `xml:"id,attr"`
Title string `xml:"title"`
Content string `xml:"content"`
}
func main() {
xmlData := `
<article id="a001">
<title>Go语言XML处理</title>
<content><![CDATA[<p>这是包含HTML标签的内容</p>]]></content>
</article>`
var article Article
err := xml.Unmarshal([]byte(xmlData), &article)
if err != nil {
fmt.Println("解析错误:", err)
return
}
fmt.Printf("文章ID: %s\n", article.ID)
fmt.Printf("内容: %s\n", article.Content)
}
6. 使用xml.Decoder流式解析
func parseXMLStream(reader io.Reader) {
decoder := xml.NewDecoder(reader)
for {
token, err := decoder.Token()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("解析错误:", err)
return
}
switch se := token.(type) {
case xml.StartElement:
if se.Name.Local == "employee" {
var emp Employee
decoder.DecodeElement(&emp, &se)
fmt.Printf("解析到员工: %s\n", emp.Name)
}
}
}
}
这些示例展示了Go语言中将XML反序列化为结构体的各种场景。关键点是正确使用结构体标签定义XML映射关系,xml.Unmarshal函数会自动根据标签将XML数据填充到对应的结构体字段中。


