V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
seers
V2EX  ›  Go 编程语言

请教一个 XML 序列化问题

  •  
  •   seers · 2022-06-02 23:37:21 +08:00 · 1425 次点击
    这是一个创建于 890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我要生成如下 xml 文件

    <?xml version="1.0" encoding="UTF-8"?>
    <svc_init ver="2.0.0">
    	<sms ver="2.0.0">
    		<client>
    			<id>id</id>
    			<pwd>pwd</pwd>
    			<serviceid>serviceid</serviceid>
    		</client>
    		<sms_info>
    			<phone>13013001300</phone>
    			<content>测试</content>
    		</sms_info>
    	</sms>
    </svc_init>
    

    代码为

    package main
    
    import (
    	"encoding/xml"
    	"fmt"
    	"os"
    )
    
    type Client struct {
    	Id        string `xml:"client>id"`
    	Pwd       string `xml:"client>pwd"`
    	Serviceid string `xml:"client>serviceid"`
    }
    
    type Sms_info struct {
    	Phone   string `xml:"sms_info>phone"`
    	Content string `xml:"sms_info>content"`
    }
    
    type Sms struct {
    	XMLName xml.Name `xml:"sms"`
    	Ver     string   `xml:"ver,attr"`
    	Client
    	Sms_info
    }
    
    type Svc_init struct {
    	XMLName xml.Name `xml:"svc_init"`
    	Ver     string   `xml:"ver,attr"`
    	Sms
    }
    
    func main() {
    	id := "id"
    	pwd := "pwd"
    	serviceid := "serviceid"
    
    	client := Client{Id: id, Pwd: pwd, Serviceid: serviceid}
    	sms_info := Sms_info{Phone: "13013001300", Content: "测试"}
    
    	sms := Sms{Ver: "2.0.0", Client: client, Sms_info: sms_info}
    
    	v := Svc_init{Ver: "2.0.0", Sms: sms}
    
    	fmt.Println(v)
    	output, _ := xml.MarshalIndent(v, "  ", "    ")
    
    	os.Stdout.Write(output)
    }
    

    运行后生成

    <svc_init ver="2.0.0">
    	<client>
    		<id>id</id>
    		<pwd>pwd</pwd>
    		<serviceid>serviceid</serviceid>
    	</client>
    	<sms_info>
    		<phone>13013001300</phone>
    		<content>测试</content>
    	</sms_info>
    </svc_init>
    

    可以看到结果的 sms 结构丢失了 但是我直接打印 v 值

    {{ } 2.0.0 {{ } 2.0.0 {id pwd serviceid} {13013001300 测试}}}
    

    可以看到 sms 结构还在 请问为什么会这样,然后如何修复呢,感谢。

    4 条回复    2022-06-04 10:00:20 +08:00
    CEBBCAT
        1
    CEBBCAT  
       2022-06-03 01:02:01 +08:00   ❤️ 1
    没用过 Go 操作 xml ,但我看你的 Client 、Sms_info 是内嵌的,考虑一下使用 https://www.onlinetool.io/xmltogo/ 生成的结构?

    另外打印的时候可以用 fmt.Printf("%+v", v),这样有字段名,好理解一点
    leonard916
        2
    leonard916  
       2022-06-03 10:13:33 +08:00
    结构里 代码写写全,IDE 没报错?
    seers
        3
    seers  
    OP
       2022-06-03 11:43:56 +08:00
    @CEBBCAT 感谢,通过页面生成的结构成功了
    MeetTheFuture
        4
    MeetTheFuture  
       2022-06-04 10:00:20 +08:00   ❤️ 1
    ```go
    package main

    import (
    "encoding/xml"
    "os"
    )

    var data = `<svc_init ver="2.0.0">
    <sms ver="2.0.0">
    <client>
    <id>id</id>
    <pwd>pwd</pwd>
    <serviceid>serviceid</serviceid>
    </client>
    <sms_info>
    <phone>13013001300</phone>
    <content>测试</content>
    </sms_info>
    </sms>
    </svc_init>`

    type Client struct {
    Id string `xml:"client>id"`
    Pwd string `xml:"client>pwd"`
    Serviceid string `xml:"client>serviceid"`
    }

    type Sms_info struct {
    Phone string `xml:"sms_info>phone"`
    Content string `xml:"sms_info>content"`
    }

    type Sms struct {
    Ver string `xml:"ver,attr"`
    Client
    Sms_info
    }

    type Svc_init struct {
    XMLName xml.Name `xml:"svc_init"`
    Ver string `xml:"ver,attr"`
    Sms Sms `xml:"sms"`
    }

    func main() {
    id := "id"
    pwd := "pwd"
    serviceid := "serviceid"

    client := Client{Id: id, Pwd: pwd, Serviceid: serviceid}
    sms_info := Sms_info{Phone: "13013001300", Content: "测试"}

    sms := Sms{Ver: "2.0.0", Client: client, Sms_info: sms_info}

    v := Svc_init{Ver: "2.0.0", Sms: sms}

    output, _ := xml.MarshalIndent(v, " ", " ")

    os.Stdout.Write(output)
    }
    ```
    给 Sms 添加了一个 `xml:"sms"` 就好了
    ```xml
    <svc_init ver="2.0.0">
    <sms ver="2.0.0">
    <client>
    <id>id</id>
    <pwd>pwd</pwd>
    <serviceid>serviceid</serviceid>
    </client>
    <sms_info>
    <phone>13013001300</phone>
    <content>测试</content>
    </sms_info>
    </sms>
    </svc_init>
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   977 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:04 · PVG 06:04 · LAX 14:04 · JFK 17:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.