golang学习笔记---xml 读取

对应 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>

  

 

 













原文地址:https://www.cnblogs.com/saryli/p/15383939.html