要读取的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)
    }

}

输出结果如图:

接下来对这个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>

###MySQL 配置信息用的实例

下面看我的 xml 格式 以及对应的解析代码

test.xml
在CODE上查看代码片派生到我的代码片

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>  
<Db>  
    <db_host>127.0.0.1</db_host>  
    <db_name>bbs</db_name>  
    <db_user>root</db_user>  
    <db_pass>123456</db_pass>  
</Db>  

test.Go

在CODE上查看代码片派生到我的代码片

package main  

import (  
    "encoding/xml"  
    "fmt"  
    "io/ioutil"  
    "os"  
)  

type Conf struct {  
    Db `xml:"Db"`  
}  

type Db struct {  
    Db_host string `xml:"db_host"`  
    Db_name string `xml:"db_name"`  
    Db_user string `xml:"db_user"`  
    Db_pass string `xml:"db_pass"`  
}  

func main() {  
    file_data, err := file_open("test.xml")  
    if err != nil {  
        fmt.Println(err.Error())  
        os.Exit(0)  
    }  
    tpl := Conf{}  
    //根据传递的构造体解析 切记 第二个参数传递的是指针  
    tpl_err := xml.Unmarshal(file_data, &tpl)  
    if tpl_err != nil {  
        fmt.Println("tpl err :", tpl_err)  
        os.Exit(0)  
    }  
    fmt.Println(tpl)  

}  

func file_open(file_name string) ([]byte, error) {  
    //定义变量  
    var (  
        open               *os.File  
        file_data          []byte  
        open_err, read_err error  
    )  
    //打开文件  
    open, open_err = os.Open(file_name)  
    if open_err != nil {  
        return nil, open_err  
    }  
    //关闭资源  
    defer open.Close()  

    //读取所有文件内容  
    file_data, read_err = ioutil.ReadAll(open)  
    if read_err != nil {  
        return nil, read_err  
    }  
    return file_data, nil  
}  

改进后应用于生产的例子

package main

import (
    "encoding/xml"
    "io/ioutil"
    "log"
)

type Conf struct {
    Db `xml:"Db"`
}

type Db struct {
    Db_host string `xml:"db_host"`
    Db_name string `xml:"db_name"`
    Db_user string `xml:"db_user"`
    Db_pass string `xml:"db_pass"`
}

func main() {

    XmlConf, err := ioutil.ReadFile("test.xml")
    if err != nil {
        log.Fatal(err)
    }
    XmlConfSet := Conf{}
    err = xml.Unmarshal(XmlConf, &XmlConfSet)
    if err != nil {
        log.Fatal(err)
    }
    var Db_host, Db_name, Db_user, Db_pass string
    Db_name = XmlConfSet.Db_name
    Db_host = XmlConfSet.Db_host
    Db_user = XmlConfSet.Db_user
    Db_pass = XmlConfSet.Db_pass
    log.Println(Db_host)
    log.Println(Db_name)
    log.Println(Db_user)
    log.Println(Db_pass)

}
文档更新时间: 2019-06-07 08:35   作者:月影鹏鹏