对应 default.xml文件
<?xml version="1.0" encoding="UTF-8"?> <config> <smtpServer>smtp.163.com</smtpServer> <smtpPort>25</smtpPort> <sender>user@163.com</sender> <senderPasswd>123456</senderPasswd> <receivers flag="true"> <user>Mike_Zhang@live.com</user> <user>test1@qq.com</user> </receivers> </config>
范例1:golang代码:
package main import ( "encoding/xml" "fmt" "io/ioutil" "os" ) type SConfig struct { XMLName xml.Name `xml:"config"` // 指定最外层的标签为config SmtpServer string `xml:"smtpServer"` // 读取smtpServer配置项,并将结果保存到SmtpServer变量中 SmtpPort int `xml:"smtpPort"` Sender string `xml:"sender"` SenderPasswd string `xml:"senderPasswd"` Receivers SReceivers `xml:"receivers"` // 读取receivers标签下的内容,以结构方式获取 } type SReceivers struct { Flag string `xml:"flag,attr"` // 读取flag属性 User []string `xml:"user"` // 读取user数组 } func main() { file, err := os.Open("default.xml") // For read access. if err != nil { fmt.Printf("error: %v", err) return } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { fmt.Printf("error: %v", err) return } v := SConfig{} err = xml.Unmarshal(data, &v) if err != nil { fmt.Printf("error: %v", err) return } fmt.Println(v) fmt.Println("SmtpServer : ", v.SmtpServer) fmt.Println("SmtpPort : ", v.SmtpPort) fmt.Println("Sender : ", v.Sender) fmt.Println("SenderPasswd : ", v.SenderPasswd) fmt.Println("Receivers.Flag : ", v.Receivers.Flag) for i, element := range v.Receivers.User { fmt.Println(i, element) } }
输出:
{{ config} smtp.163.com 25 user@163.com 123456 {true [Mike_Zhang@live.com test1@qq.com]}}
SmtpServer : smtp.163.com
SmtpPort : 25
Sender : user@163.com
SenderPasswd : 123456
Receivers.Flag : true
0 Mike_Zhang@live.com
1 test1@qq.com
范例2:
要读取的XML如下:
<?xml version="1.0" encoding="UTF-8"?> <resources> <string name="VideoLoading">Loading video…</string> <string name="ApplicationName">what</string> </resources>
这种结构的XML,其末节点是属性与文本并存的
根据这个XML,生成对应的struct
type StringResources struct { XMLName xml.Name `xml:"resources"` ResourceString []ResourceString `xml:"string"` } type ResourceString struct { XMLName xml.Name `xml:"string"` StringName string `xml:"name,attr"` InnerText string `xml:",innerxml"` }
内部属性都要大写字母开头,属性节点的名称变量名固定为XMLName,内部的文本统一叫innerxml)
以下为完整读取此XML的代码
package main import ( "encoding/xml" "io/ioutil" "log" ) type StringResources struct { XMLName xml.Name `xml:"resources"` ResourceString []ResourceString `xml:"string"` } type ResourceString struct { XMLName xml.Name `xml:"string"` StringName string `xml:"name,attr"` InnerText string `xml:",innerxml"` } func main() { content, err := ioutil.ReadFile("studygolang.xml") if err != nil { log.Fatal(err) } var result StringResources err = xml.Unmarshal(content, &result) if err != nil { log.Fatal(err) } log.Println(result) log.Println(result.ResourceString) for _, o := range result.ResourceString { log.Println(o.StringName + "===" + o.InnerText) } }
输出结果:
2021/10/09 09:08:58 {{ resources} [{{ string} VideoLoading Loading video…} {{ string} ApplicationName what}]} 2021/10/09 09:08:59 [{{ string} VideoLoading Loading video…} {{ string} ApplicationName what}] 2021/10/09 09:08:59 VideoLoading===Loading video… 2021/10/09 09:08:59 ApplicationName===what
接下来对这个XMl中的属性值为ApplicationName的文本内容进行修改,然后保存到文件里,代码如下:
package main import ( "encoding/xml" "fmt" "io/ioutil" "log" "os" "strings" ) type StringResources struct { XMLName xml.Name `xml:"resources"` ResourceString []ResourceString `xml:"string"` } type ResourceString struct { XMLName xml.Name `xml:"string"` StringName string `xml:"name,attr"` InnerText string `xml:",innerxml"` } func main() { content, err := ioutil.ReadFile("studygolang.xml") if err != nil { log.Fatal(err) } var result StringResources err = xml.Unmarshal(content, &result) if err != nil { log.Fatal(err) } log.Println(result) log.Println(result.ResourceString) for i, line := range result.ResourceString { log.Println(line.StringName + "===" + line.InnerText) //修改ApplicationName节点的内部文本innerText if strings.EqualFold(line.StringName, "ApplicationName") { fmt.Println("change innerText") //注意修改的不是line对象,而是直接使用result中的真实对象 result.ResourceString[i].InnerText = "这是新的ApplicationName" } } //保存修改后的内容 xmlOutPut, outPutErr := xml.MarshalIndent(result, "", "") if outPutErr == nil { //加入XML头 headerBytes := []byte(xml.Header) //拼接XML头和实际XML内容 xmlOutPutData := append(headerBytes, xmlOutPut...) //写入文件 ioutil.WriteFile("studygolang_test.xml", xmlOutPutData, os.ModeAppend) fmt.Println("OK~") } else { fmt.Println(outPutErr) } }
生成的XML如下:
<?xml version="1.0" encoding="UTF-8"?> <resources> <string name="VideoLoading">Loading video…</string> <string name="ApplicationName">这是新的ApplicationName</string> </resources>